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

Author Topic: Does sf::Text works in a OpenGL Core profile example?  (Read 11502 times)

0 Members and 1 Guest are viewing this topic.

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Does sf::Text works in a OpenGL Core profile example?
« on: August 18, 2013, 10:41:28 pm »
Hi,

I am trying to execute the following example (OpenGL Core profile) and when I try to draw a text it displays the following error at the console:

"An internal OpenGL call failed in RenderTarget.cpp (218) : GL_INVALID_OPERATION,
 the specified operation is not allowed in the current state"

The question is:

I have read in other threads that some features are not available for OpenGL core/

Is it posible to use SFML Text using opengl core profile?


Thanks,
Nicolas

#define GLEW_STATIC

#include <GL/glew.h>

#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

#include <glm/glm.hpp>
using glm::mat4;
using glm::vec3;
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform2.hpp>

#include <fstream>
#include <sstream>
#include <string>

#include "GLSLProgram.h"

GLuint theProgram;



int main()
{
        sf::ContextSettings contextSettings;
        contextSettings.depthBits = 32;
        contextSettings.stencilBits = 8;
        contextSettings.antialiasingLevel = 4;
        contextSettings.majorVersion = 0;
        contextSettings.minorVersion = 1;

        // Create the main window
        sf::RenderWindow window(sf::VideoMode(640, 480), "SFML window with OpenGL", sf::Style::Default, contextSettings);

        // Make it the active window for OpenGL calls
        window.setActive();

        GLenum err = glewInit();
        if( GLEW_OK != err )
        {
                fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(err) );
        }

        const GLubyte *renderer = glGetString( GL_RENDERER );
        const GLubyte *vendor = glGetString( GL_VENDOR );
        const GLubyte *version = glGetString( GL_VERSION );
        const GLubyte *glslVersion =
                glGetString( GL_SHADING_LANGUAGE_VERSION );
        GLint major, minor;
        glGetIntegerv(GL_MAJOR_VERSION, &major);
        glGetIntegerv(GL_MINOR_VERSION, &minor);
        printf("GL Vendor : %s\n", vendor);
        printf("GL Renderer : %s\n", renderer);
        printf("GL Version (string) : %s\n", version);
        printf("GL Version (integer) : %d.%d\n", major, minor);
        printf("GLSL Version : %s\n", glslVersion);

                // Create some text to draw on top of our OpenGL object
    sf::Font font;

    if (!font.loadFromFile("resources/sansation.ttf"))
        return EXIT_FAILURE;
   
        sf::Text text("SFML / OpenGL demo", font);
    text.setColor(sf::Color(255, 255, 255, 170));
    text.setPosition(250.f, 250.f);
        // Bind the texture
    glEnable(GL_TEXTURE_2D);

        // Compile and link Shaders
        GLSLProgram prog;
        if( ! prog.compileShaderFromFile("shaders/basic_affinetransform.vert",GLSLShader::VERTEX) )
        {
                printf("Vertex shader failed to compile!\n%s",
                        prog.log().c_str());
                exit(1);
        }
        if( ! prog.compileShaderFromFile("shaders/basic_affinetransform.frag",GLSLShader::FRAGMENT))
        {
                printf("Fragment shader failed to compile!\n%s",
                        prog.log().c_str());
                exit(1);
        }
        if( ! prog.link() )
        {
                printf("Shader program failed to link!\n%s",
                        prog.log().c_str());
                exit(1);
        }

        float matrix[] = {
                1.0f, 0.0f, 0.0f, 0.0f, // first column
                0.0f, 1.0f, 0.0f, 0.0f, // second column
                0.0f, 0.0f, 1.0f, 0.0f, // third column
                0.5f, 0.0f, 0.0f, 1.0f // fourth column
        };

        int matrix_location = glGetUniformLocation (prog.getHandle(), "matrix");
        glUseProgram (prog.getHandle());
        glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix);

        prog.use();

        /////////////////// Create the VBO ////////////////////

        float positionData[] = {
        -0.8f, -0.8f, 0.0f,
         0.8f, -0.8f, 0.0f,
         0.0f, 0.8f, 0.0f };

        float colorData[] = {
                1.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 1.0f };


        // Create and populate the buffer objects
        GLuint vboHandles[2];

        // Create the buffer objects
        glGenBuffers(2, vboHandles);
        GLuint positionBufferHandle = vboHandles[0];
        GLuint colorBufferHandle = vboHandles[1];

        // Populate the position buffer
        glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
        glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW);

        // Populate the color buffer
        glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
        glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colorData, GL_STATIC_DRAW);

        // Create and set-up the vertex array object
        GLuint vaoHandle;
        glGenVertexArrays( 1, &vaoHandle );
        glBindVertexArray(vaoHandle);

        // Enable the vertex attribute arrays
        glEnableVertexAttribArray(0); // Vertex position
        glEnableVertexAttribArray(1); // Vertex color

        // Map index 0 to the position buffer
        glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
        glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

        // Map index 1 to the color buffer
        glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
        glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glClearColor(0.0,0.0,0.0,1.0);
        glEnable(GL_DEPTH_TEST);

        // Configure the viewport (the same size as the window)
        glViewport(0, 0, window.getSize().x, window.getSize().y);

        // Create a clock for measuring the time elapsed
        sf::Clock clock;

        // Start the game loop
        while (window.isOpen())
        {
                // Process events
                sf::Event event;
                while (window.pollEvent(event))
                {
                        // Close window: exit
                        if (event.type == sf::Event::Closed) {
                                window.close();
                                return EXIT_SUCCESS;
                        }

                        // Escape key: exit
                        if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)) {
                                window.close();
                                return EXIT_SUCCESS;
                        }

                        // Resize event: adjust the viewport
                        if (event.type == sf::Event::Resized) {
                                glViewport(0, 0, event.size.width, event.size.height);
                        }
                }

                //// Clear the color and depth buffers
                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                //matrix[12] += 0.0001f;
                //glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix);


                //glBindVertexArray(vaoHandle);
                //glDrawArrays(GL_TRIANGLES, 0, 3 );

                // Draw some text on top of our OpenGL object
        window.pushGLStates();
        window.draw(text);
        window.popGLStates();

                window.display();

        }



        return EXIT_SUCCESS;
}
 

#include "glslprogram.h"

#include <fstream>
using std::ifstream;
using std::ios;

#include <sstream>
using std::ostringstream;

#include <sys/stat.h>

GLSLProgram::GLSLProgram() : handle(0), linked(false) { }

bool GLSLProgram::compileShaderFromFile( const char * fileName,
                                         GLSLShader::GLSLShaderType type )
{
    if( ! fileExists(fileName) )
    {
        logString = "File not found.";
        return false;
    }

    if( handle <= 0 ) {
        handle = glCreateProgram();
        if( handle == 0) {
            logString = "Unable to create shader program.";
            return false;
        }
    }

    ifstream inFile( fileName, ios::in );
    if( !inFile ) {
        return false;
    }

    ostringstream code;
    while( inFile.good() ) {
        int c = inFile.get();
        if( ! inFile.eof() )
            code << (char) c;
    }
    inFile.close();

    return compileShaderFromString(code.str(), type);
}

bool GLSLProgram::compileShaderFromString( const string & source, GLSLShader::GLSLShaderType type )
{
    if( handle <= 0 ) {
        handle = glCreateProgram();
        if( handle == 0) {
            logString = "Unable to create shader program.";
            return false;
        }
    }

    GLuint shaderHandle = 0;

    switch( type ) {
    case GLSLShader::VERTEX:
        shaderHandle = glCreateShader(GL_VERTEX_SHADER);
        break;
    case GLSLShader::FRAGMENT:
        shaderHandle = glCreateShader(GL_FRAGMENT_SHADER);
        break;
    case GLSLShader::GEOMETRY:
        shaderHandle = glCreateShader(GL_GEOMETRY_SHADER);
        break;
    case GLSLShader::TESS_CONTROL:
        shaderHandle = glCreateShader(GL_TESS_CONTROL_SHADER);
        break;
    case GLSLShader::TESS_EVALUATION:
        shaderHandle = glCreateShader(GL_TESS_EVALUATION_SHADER);
        break;
    default:
        return false;
    }

    const char * c_code = source.c_str();
    glShaderSource( shaderHandle, 1, &c_code, NULL );

    // Compile the shader
    glCompileShader(shaderHandle );

    // Check for errors
    int result;
    glGetShaderiv( shaderHandle, GL_COMPILE_STATUS, &result );
    if( GL_FALSE == result ) {
        // Compile failed, store log and return false
        int length = 0;
        logString = "";
        glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &length );
        if( length > 0 ) {
            char * c_log = new char[length];
            int written = 0;
            glGetShaderInfoLog(shaderHandle, length, &written, c_log);
            logString = c_log;
            delete [] c_log;
        }

        return false;
    } else {
        // Compile succeeded, attach shader and return true
        glAttachShader(handle, shaderHandle);
        return true;
    }
}

bool GLSLProgram::link()
{
    if( linked ) return true;
    if( handle <= 0 ) return false;

    glLinkProgram(handle);

    int status = 0;
    glGetProgramiv( handle, GL_LINK_STATUS, &status);
    if( GL_FALSE == status ) {
        // Store log and return false
        int length = 0;
        logString = "";

        glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &length );

        if( length > 0 ) {
            char * c_log = new char[length];
            int written = 0;
            glGetProgramInfoLog(handle, length, &written, c_log);
            logString = c_log;
            delete [] c_log;
        }

        return false;
    } else {
        linked = true;
        return linked;
    }
}

void GLSLProgram::use()
{
    if( handle <= 0 || (! linked) ) return;
    glUseProgram( handle );
}

string GLSLProgram::log()
{
    return logString;
}

int GLSLProgram::getHandle()
{
    return handle;
}

bool GLSLProgram::isLinked()
{
    return linked;
}

void GLSLProgram::bindAttribLocation( GLuint location, const char * name)
{
    glBindAttribLocation(handle, location, name);
}

void GLSLProgram::bindFragDataLocation( GLuint location, const char * name )
{
    glBindFragDataLocation(handle, location, name);
}

void GLSLProgram::setUniform( const char *name, float x, float y, float z)
{
    int loc = getUniformLocation(name);
    if( loc >= 0 ) {
        glUniform3f(loc,x,y,z);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, const vec3 & v)
{
    this->setUniform(name,v.x,v.y,v.z);
}

void GLSLProgram::setUniform( const char *name, const vec4 & v)
{
    int loc = getUniformLocation(name);
    if( loc >= 0 ) {
        glUniform4f(loc,v.x,v.y,v.z,v.w);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, const vec2 & v)
{
    int loc = getUniformLocation(name);
    if( loc >= 0 ) {
        glUniform2f(loc,v.x,v.y);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, const mat4 & m)
{
    int loc = getUniformLocation(name);
    if( loc >= 0 )
    {
        glUniformMatrix4fv(loc, 1, GL_FALSE, &m[0][0]);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, const mat3 & m)
{
    int loc = getUniformLocation(name);
    if( loc >= 0 )
    {
        glUniformMatrix3fv(loc, 1, GL_FALSE, &m[0][0]);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, float val )
{
    int loc = getUniformLocation(name);
    if( loc >= 0 )
    {
        glUniform1f(loc, val);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, int val )
{
    int loc = getUniformLocation(name);
    if( loc >= 0 )
    {
        glUniform1i(loc, val);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::setUniform( const char *name, bool val )
{
    int loc = getUniformLocation(name);
    if( loc >= 0 )
    {
        glUniform1i(loc, val);
    } else {
        printf("Uniform: %s not found.\n",name);
    }
}

void GLSLProgram::printActiveUniforms() {

    GLint nUniforms, size, location, maxLen;
    GLchar * name;
    GLsizei written;
    GLenum type;

    glGetProgramiv( handle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
    glGetProgramiv( handle, GL_ACTIVE_UNIFORMS, &nUniforms);

    name = (GLchar *) malloc( maxLen );

    printf(" Location | Name\n");
    printf("------------------------------------------------\n");
    for( int i = 0; i < nUniforms; ++i ) {
        glGetActiveUniform( handle, i, maxLen, &written, &size, &type, name );
        location = glGetUniformLocation(handle, name);
        printf(" %-8d | %s\n",location, name);
    }

    free(name);
}

void GLSLProgram::printActiveAttribs() {

    GLint written, size, location, maxLength, nAttribs;
    GLenum type;
    GLchar * name;

    glGetProgramiv(handle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
    glGetProgramiv(handle, GL_ACTIVE_ATTRIBUTES, &nAttribs);

    name = (GLchar *) malloc( maxLength );

    printf(" Index | Name\n");
    printf("------------------------------------------------\n");
    for( int i = 0; i < nAttribs; i++ ) {
        glGetActiveAttrib( handle, i, maxLength, &written, &size, &type, name );
        location = glGetAttribLocation(handle, name);
        printf(" %-5d | %s\n",location, name);
    }

    free(name);
}

bool GLSLProgram::validate()
{
    if( ! isLinked() ) return false;

    GLint status;
    glValidateProgram( handle );
    glGetProgramiv( handle, GL_VALIDATE_STATUS, &status );

    if( GL_FALSE == status ) {
        // Store log and return false
        int length = 0;
        logString = "";

        glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &length );

        if( length > 0 ) {
            char * c_log = new char[length];
            int written = 0;
            glGetProgramInfoLog(handle, length, &written, c_log);
            logString = c_log;
            delete [] c_log;
        }

        return false;
    } else {
       return true;
    }
}

int GLSLProgram::getUniformLocation(const char * name )
{
    return glGetUniformLocation(handle, name);
}

bool GLSLProgram::fileExists( const string & fileName )
{
    struct stat info;
    int ret = -1;

    ret = stat(fileName.c_str(), &info);
    return 0 == ret;
}
 

#ifndef GLSLPROGRAM_H
#define GLSLPROGRAM_H

#include <string>
using std::string;

#include <GL/glew.h>

#include <glm/glm.hpp>
using glm::vec2;
using glm::vec3;
using glm::vec4;
using glm::mat4;
using glm::mat3;

namespace GLSLShader {
    enum GLSLShaderType {
        VERTEX, FRAGMENT, GEOMETRY,
        TESS_CONTROL, TESS_EVALUATION
    };
};

class GLSLProgram
{
private:
    int handle;
    bool linked;
    string logString;

    int getUniformLocation(const char * name );
    bool fileExists( const string & fileName );

public:
    GLSLProgram();

    bool compileShaderFromFile( const char * fileName, GLSLShader::GLSLShaderType type );
    bool compileShaderFromString( const string & source, GLSLShader::GLSLShaderType type );
    bool link();
    bool validate();
    void use();

    string log();

    int getHandle();
    bool isLinked();

    void bindAttribLocation( GLuint location, const char * name);
    void bindFragDataLocation( GLuint location, const char * name );

    void setUniform( const char *name, float x, float y, float z);
    void setUniform( const char *name, const vec2 & v);
    void setUniform( const char *name, const vec3 & v);
    void setUniform( const char *name, const vec4 & v);
    void setUniform( const char *name, const mat4 & m);
    void setUniform( const char *name, const mat3 & m);
    void setUniform( const char *name, float val );
    void setUniform( const char *name, int val );
    void setUniform( const char *name, bool val );

    void printActiveUniforms();
    void printActiveAttribs();
};

#endif // GLSLPROGRAM_H
 

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #1 on: August 18, 2013, 10:54:58 pm »
sfml-graphics still uses deprecated functions, so it can't be used with a core profile. And it's not just sf::Text (look, the error occurs in RenderTarget.cpp).

But SFML shouldn't be able to create contexts that it cannot use, how do you know that it's a core context and what's your OS?
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #2 on: August 18, 2013, 11:02:53 pm »
Hi,

I am not using an opengl core context, I use the SFML context :), but I am programming assuming that I have an opengl core context except when I use SFML features such as Text.
I wonder if it is is possible to do that?

In the example I included in the thread, I had been trying to display a triangle (using OpenGL core features) and after that I am trying to display a text " window.draw(text);".

To display the triangle , I use a raw VBO and VAO. Also I use my custom Vertex and Fragment shaders.

I wonder if it is in some way incompatible to use OpenGl core and SFML Texts , or maybe there is some workaround?

I am working with Windows 7 64 bits, and Visual studio 2012 64 bits compiler.

Thanks,
Nicolas


Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #3 on: August 18, 2013, 11:18:16 pm »
Before investigating, please reduce the code to a complete and minimal program that reproduces the problem. The error could be triggered by anything.
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #4 on: August 18, 2013, 11:34:30 pm »
Hi,

I tried to simplify as much as I can :)

If you comment :
        window.pushGLStates();
        window.draw(text);
        window.popGLStates();
it works displaying the triangle but the text is not displayed because is commented. You need to include the font file that is in SFML examples.

With those 3 lines, is displays the
"An internal OpenGL call failed in RenderTarget.cpp (218) : GL_INVALID_OPERATION,
 the specified operation is not allowed in the current state"
error.

Thanks,
Nicolas.

//To summarize, rendering with vertex buffer objects (VBOs) involves the following steps:
//1. Before linking the shader program, define the mappings between generic vertex
//attribute indexes and shader input variables by calling glBindAttribLocation.
//2. Create and populate the buffer objects for each attribute.
//3. Create and define the vertex array object by calling glVertexAttribPointer
//while the appropriate buffer is bound.
//4. When rendering, bind to the vertex array object and call glDrawArrays, or other
//appropriate rendering function (for example, glDrawElements).
#define GLEW_STATIC

#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile)
{
        GLuint shader = glCreateShader(eShaderType);
        const char *strFileData = strShaderFile.c_str();
        glShaderSource(shader, 1, &strFileData, NULL);

        glCompileShader(shader);

        GLint status;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
        if (status == GL_FALSE)
        {
                GLint infoLogLength;
                glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);

                GLchar *strInfoLog = new GLchar[infoLogLength + 1];
                glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);

                const char *strShaderType = NULL;
                switch(eShaderType)
                {
                case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
                case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
                case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
                }

                fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog);
                delete[] strInfoLog;
        }

        return shader;
}

GLuint CreateProgram(const std::vector<GLuint> &shaderList)
{
        GLuint program = glCreateProgram();

        // Bind index 0 to the shader input variable "VertexPosition"
    glBindAttribLocation(program, 0, "VertexPosition");
    // Bind index 1 to the shader input variable "VertexColor"
    glBindAttribLocation(program, 1, "VertexColor");

        //The output variable FragColor in the fragment shader. This variable receives the final output color for each
        //fragment (pixel). Like vertex input variables, this variable also needs to be associated with
        //a location. Of course, we typically would like this to be linked to the back color buffer, which
        //by default (in double buffered systems) is "color number" zero.
        glBindFragDataLocation(program, 0, "FragColor");

        for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
                glAttachShader(program, shaderList[iLoop]);

        glLinkProgram(program);

        GLint status;
        glGetProgramiv (program, GL_LINK_STATUS, &status);
        if (status == GL_FALSE)
        {
                GLint infoLogLength;
                glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);

                GLchar *strInfoLog = new GLchar[infoLogLength + 1];
                glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
                fprintf(stderr, "Linker failure: %s\n", strInfoLog);
                delete[] strInfoLog;
        }

        for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
                glDetachShader(program, shaderList[iLoop]);

        return program;
}

GLuint theProgram;

const std::string strVertexShader(
        "#version 400\n"
        "in vec3 VertexPosition;\n"
        "in vec3 VertexColor;\n"
        "out vec3 Color;\n"
        "void main()\n"
        "{\n"
        "Color = VertexColor;\n"
        "gl_Position = vec4(VertexPosition,1.0);\n"
        "}\n"
);

const std::string strFragmentShader(
        "#version 400\n"
        "in vec3 Color;\n"
        "out vec4 FragColor;\n"
        "void main() {\n"
        "FragColor = vec4(Color, 1.0);\n"
        "}\n"
);

void InitializeProgram()
{
        std::vector<GLuint> shaderList;

        shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader));
        shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));

        theProgram = CreateProgram(shaderList);

        std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader);
}


int main()
{
        sf::ContextSettings contextSettings;
        contextSettings.depthBits = 32;
        contextSettings.stencilBits = 8;
        contextSettings.antialiasingLevel = 4;
        contextSettings.majorVersion = 3;
        contextSettings.minorVersion = 1;

        // Create the main window
        sf::RenderWindow window(sf::VideoMode(640, 480), "SFML window with OpenGL", sf::Style::Default, contextSettings);

        // Make it the active window for OpenGL calls
        window.setActive();

        GLenum err = glewInit();
        if( GLEW_OK != err )
        {
                fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(err) );
        }

        // Create some text to draw on top of our OpenGL object
    sf::Font font;
    if (!font.loadFromFile("resources/sansation.ttf"))
        return EXIT_FAILURE;
    sf::Text text("SFML / OpenGL demo", font);
    text.setColor(sf::Color(255, 255, 255, 170));
    text.setPosition(250.f, 450.f);

        InitializeProgram();

        /////////////////// Create the VBO ////////////////////
           
        float positionData[] = {
        -0.8f, -0.8f, 0.0f,
         0.8f, -0.8f, 0.0f,
         0.0f, 0.8f, 0.0f };
    float colorData[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f };


    // Create and populate the buffer objects
    GLuint vboHandles[2];

        // Create the buffer objects
    glGenBuffers(2, vboHandles);
    GLuint positionBufferHandle = vboHandles[0];
    GLuint colorBufferHandle = vboHandles[1];

        // Populate the position buffer
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW);

        // Populate the color buffer
    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colorData, GL_STATIC_DRAW);

    // Create and set-up the vertex array object
        GLuint vaoHandle;
    glGenVertexArrays( 1, &vaoHandle );
    glBindVertexArray(vaoHandle);

        // Enable the vertex attribute arrays
    glEnableVertexAttribArray(0); // Vertex position
    glEnableVertexAttribArray(1); // Vertex color

        // Map index 0 to the position buffer
        glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );

        // Map index 1 to the color buffer
    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
       
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        // Configure the viewport (the same size as the window)
        glViewport(0, 0, window.getSize().x, window.getSize().y);

        // Create a clock for measuring the time elapsed
        sf::Clock clock;

        // Start the game loop
        while (window.isOpen())
        {
                // Process events
                sf::Event event;
                while (window.pollEvent(event))
                {
                        // Close window: exit
                        if (event.type == sf::Event::Closed)
                                window.close();

                        // Escape key: exit
                        if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                                window.close();

                        // Resize event: adjust the viewport
                        if (event.type == sf::Event::Resized)
                                glViewport(0, 0, event.size.width, event.size.height);
                }

                //// Clear the color and depth buffers
                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                glClear(GL_COLOR_BUFFER_BIT);

                glUseProgram(theProgram);

                // In the render function, bind to the vertex array object
                // and call glDrawArrays to initiate rendering.
                glBindVertexArray(vaoHandle);
                glDrawArrays(GL_TRIANGLES, 0, 3 );

                // Draw some text on top of our OpenGL object
        window.pushGLStates();
        window.draw(text);
        window.popGLStates();

                window.display();
        }

        return EXIT_SUCCESS;
}
 
« Last Edit: August 18, 2013, 11:36:57 pm by nicoraf »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #5 on: August 19, 2013, 07:53:08 am »
You should try with SFML calls only, and then add OpenGL calls until the errors occurs again (we don't care if the program works or not, we just want to see the error).
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #6 on: August 19, 2013, 09:03:08 pm »
Hi, i will try to figure to reduce it more, take into account that it is necessary to load the fragment and vertx shaders and the triangle data also. The other code is sfml related , if I find a way to reduce more i will post it but it is almost a hello world opengl core example.
Thanks,
Nicolas
« Last Edit: August 19, 2013, 09:05:01 pm by nicoraf »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #7 on: August 19, 2013, 09:23:59 pm »
Quote
take into account that it is necessary to load the fragment and vertx shaders and the triangle data also
My guess is that you don't need to draw anything to produce the error. It must be caused by a state that you set.
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #8 on: August 19, 2013, 09:28:23 pm »
Yes the issue is caused by using VBO and VAO instead if legacy opengl primitives to display the triangle.

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #9 on: August 20, 2013, 06:19:22 am »
Simplified the example as Laurent suggested. There are some commented lines to understand the context.
Any help will be appreciated.



#define GLEW_STATIC

#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>

int main()
{
    sf::ContextSettings contextSettings;
    contextSettings.depthBits = 32;
    contextSettings.stencilBits = 8;
    contextSettings.antialiasingLevel = 4;
    contextSettings.majorVersion = 3;
    contextSettings.minorVersion = 1;

    // Create the main window
    sf::RenderWindow window(sf::VideoMode(640, 480), "SFML window with OpenGL", sf::Style::Default, contextSettings);

    // Make it the active window for OpenGL calls
    window.setActive();

    GLenum err = glewInit();
    if( GLEW_OK != err )
    {
        fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(err) );
    }

    // Create some text to draw on top of our OpenGL object
    sf::Font font;
    if (!font.loadFromFile("resources/sansation.ttf"))
        return EXIT_FAILURE;
    sf::Text text("SFML / OpenGL demo", font);
    text.setColor(sf::Color(255, 255, 255, 170));
    text.setPosition(250.f, 450.f);

    /////////////////// Create the VBO ////////////////////
     
    float positionData[] = {
        -0.8f, -0.8f, 0.0f,
         0.8f, -0.8f, 0.0f,
         0.0f, 0.8f, 0.0f };

    // Create and populate the buffer objects
    GLuint vboHandles[1];

    // Create the buffer objects
    glGenBuffers(1, vboHandles);
    GLuint positionBufferHandle = vboHandles[0];

    // Populate the position buffer
    glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW);

    // Create and set-up the vertex array object
    GLuint vaoHandle;
    glGenVertexArrays( 1, &vaoHandle );
    glBindVertexArray(vaoHandle);

    //// Enable the vertex attribute arrays
    //glEnableVertexAttribArray(0); // Vertex position

    //// Map index 0 to the position buffer
    //glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    //glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL );
   
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Configure the viewport (the same size as the window)
    glViewport(0, 0, window.getSize().x, window.getSize().y);

    // Create a clock for measuring the time elapsed
    sf::Clock clock;

    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Resize event: adjust the viewport
            if (event.type == sf::Event::Resized)
                glViewport(0, 0, event.size.width, event.size.height);
        }

        // Here can be custom OpenGL drawing code


        // Draw some text on top of our OpenGL object
        window.pushGLStates();
        window.draw(text);
        window.popGLStates();

        window.display();
    }

    return EXIT_SUCCESS;
}
 
 
 
« Last Edit: August 20, 2013, 06:27:28 am by nicoraf »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #10 on: August 20, 2013, 07:44:57 am »
So if you remove any of your OpenGL calls, it works?
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #11 on: August 20, 2013, 04:46:30 pm »
If I comment glBindVertexArray line it doesnt crash and displays the sfml text for me. Thanks

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #12 on: August 20, 2013, 04:59:29 pm »
Crash? I thought we were talking about an error message in the console (although a crash is more expected in this situation).

To solve the crash, try calling glBindVertexArray(0). But I'd really like to solve this error message ;)
Laurent Gomila - SFML developer

nicoraf

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #13 on: August 21, 2013, 10:01:00 pm »
Thanks Laurent, I think that this can be solved if SFML uses some fixed particular VAO and VBO for the textures usef for the fonts. Maybe there is no standard way to support opengl core and opengl legacy primitives at the same time or that is possible to do ?

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Does sf::Text works in a OpenGL Core profile example?
« Reply #14 on: August 22, 2013, 01:03:27 am »
Thanks Laurent, I think that this can be solved if SFML uses some fixed particular VAO and VBO for the textures usef for the fonts. Maybe there is no standard way to support opengl core and opengl legacy primitives at the same time or that is possible to do ?
? ? ?

This is not a bug, and as such there is nothing to fix.

SFML already forces the operating system to give it a context that supports the deprecated OpenGL interfaces i.e a compatibility context. You can't get a "core only" context if you use SFML for context management. So if you use an SFML context with a high enough version number there should never be any GL_INVALID_OPERATION errors due to removed functions. The only time that error can occur is when something really does go wrong, and you should look for the source of that error instead of wondering whether it has something to do with deprecation or not.

And no, I don't think Laurent is going to consider using VAOs inside SFML just yet. It would cut off too many users with older hardware who are happily running SFML as it is with pre-3.0 OpenGL right now. Not only that, even if SFML did use VAOs it would not be able to provide any significant performance increase anyway, which would be a complete waste of time.

VAOs are a very very advanced topic. It takes time to understand how they work and what they are for. It takes even more time to understand how you can use them effectively, and even more time to test whether they actually make a difference. If you really want to play around with VAOs and SFML, you should really look at the SFML source a lot more and not just rely on the documentation. It is written to provide as much information as possible for the "normal" user, but for people like you who use newer OpenGL that is really sensitive to anything that is done, knowing exactly what and how SFML uses OpenGL is necessary. One thing that many people are still not aware of is that VAOs are one of the few resources that are not shared between contexts. Guess what happens if you call glBindVertexArray() in the wrong context? GL_INVALID_OPERATION, and have fun debugging. Hopefully Laurent won't linger with this shared context framework for too long. It is not future proof considering newer OpenGL resources probably won't be shareable either.

Oh, and pushGLStates() and popGLStates() won't help you either when using VAOs. You should develop a good habit of cleaning up after yourself and unbinding any arrays and doing attribute housekeeping before letting other people mess with OpenGL. Leaving the same array bound the whole time defeats the purpose of a VAO anyway...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).