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

Author Topic: sfml2, opengl3.2 and glCreateShader  (Read 7338 times)

0 Members and 1 Guest are viewing this topic.

Revan1985

  • Newbie
  • *
  • Posts: 4
    • MSN Messenger - davide_galli_420@hotmail.it
    • View Profile
sfml2, opengl3.2 and glCreateShader
« on: December 07, 2010, 09:58:56 pm »
Hi all.
I'm trying to develop an application using opengl 3/4 and sfml2.
I've decided to use sfml after some framework (sdl & glut in primis).
Now, i've a little problem creating the shader.

I've builded a class for Shader usage (i've not seen there was a Shader class in sfml  :oops: ), and there are some problems.
When i execute the code, i've an exception on glCreateSahder(GL_VERTEX_SHADER), and i don't understand why.

As first thing, i've thinked the glew was not initialized, but when i try the get any error from it, i've always OK.
Second, a different version of glew.
I'm using the last, 1.5.7, when sfml not (it's a different size, and other things), so, i've sobsituted the sfml version with last, rebuilded, and recompiled my program, but nothing.

What can be happened?

Here my code

main.cpp
Code: [Select]

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

#include <gl/glew.h>
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "opengl32.lib")

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_projection.hpp>

#include "Shader.hpp"

int main(int argc, char** argv)
{
sf::ContextSettings settings;
settings.MajorVersion = 3;
settings.MinorVersion = 2;

settings.DepthBits = 24;
settings.StencilBits = 8;
settings.AntialiasingLevel = 2;

sf::Shader shd;
sf::RenderWindow App(sf::VideoMode(1280, 720), "SFML Window", sf::Style::Default, settings);

std::cout << "Current Using opengl : " << App.GetSettings().MajorVersion << "." << App.GetSettings().MinorVersion << std::endl;
Shader* shader = new Shader("shader.vert", "shader.frag");

glm::mat4 viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
glm::mat4 modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
glm::mat4 projectionMatrix  = glm::perspective(60.0f, (float)App.GetWidth() / (float)App.GetHeight(), 0.1f, 100.0f);

glClearColor(0.4f, 0.6f, 0.9f, 0.0f);

while(App.IsOpened())
{
sf::Event evt;
while(App.GetEvent(evt))
{
switch(evt.Type)
{
case sf::Event::Closed:
App.Close();
break;
case sf::Event::Resized:
glViewport(0, 0, evt.Size.Width, evt.Size.Height);
projectionMatrix = glm::perspective(60.0f, (float)evt.Size.Width / (float)evt.Size.Height, 0.1f, 100.0f);
break;
case sf::Event::KeyPressed:
{
switch(evt.Key.Code)
{
case sf::Key::Escape:
App.Close();
}
}
break;
}
}
float frameRate = 1.0f / App.GetFrameTime();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));

shader->bind();

int viewMatrixLocation = glGetUniformLocation(shader->id(), "viewMatrix");
int modelMatrixLocation = glGetUniformLocation(shader->id(), "modelMatrix");
int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix");

glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);
glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);
glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]);

shader->unbind();

App.Display();
}

if(shader)
{
delete shader;
shader = 0;
}

return EXIT_SUCCESS;
}


shader.hpp
Code: [Select]

#ifndef _SHADER_HPP_
#define _SHADER_HPP_

#include <gl/glew.h>
#include <iostream>

class Shader
{
public:
Shader(); // Costruttore di Default
~Shader(); // Distruttore

Shader(const std::string& vsFile, const std::string& fsFile); // Costruttore per creare gli shader da 1 files.
void init(const std::string& vsFile, const std::string& fsFile); // Inizializza lo shader con i file passati

void bind();
void unbind();

unsigned int id() const { return shader_id; }

private:
unsigned int shader_id; // L'identificatore del program
unsigned int shader_fp; // L'identificatore del fragment shader
unsigned int shader_vp; // L'identificatore del vertex shader

bool inited; // Ho inizializzato la classe?
};

#endif


shader.cpp
Code: [Select]

#include "Shader.hpp"

#include <string>
#include <fstream>

using namespace std;

static string textFileRead(const string& filename)
{
string line = string();
string filestring = string();
ifstream file(filename);

if(file.is_open())
{
while(!file.eof())
{
getline(file, line);
filestring.append(line);
filestring.append("\n");
}
file.close();
}
return filestring;
}

/**
Given a shader and the filename associated with it, validateShader will
then get information from OpenGl on whether or not the shader was compiled successfully
and if it wasn't, it will output the file with the problem, as well as the problem.
*/
static void validateShader(GLuint shader, const string& file = 0) {
    const unsigned int BUFFER_SIZE = 512;
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    GLsizei length = 0;
   
    glGetShaderInfoLog(shader, BUFFER_SIZE, &length, buffer); // Ask OpenGL to give us the log associated with the shader
    if (length > 0) // If we have any information to display
        cout << "Shader " << shader << " (" << (file.length() > 0 ? file : "") << ") compile error: " << buffer << endl; // Output the information
}

/**
Given a shader program, validateProgram will request from OpenGL, any information
related to the validation or linking of the program with it's attached shaders. It will
then output any issues that have occurred.
*/
static void validateProgram(GLuint program) {
    const unsigned int BUFFER_SIZE = 512;
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    GLsizei length = 0;
   
    glGetProgramInfoLog(program, BUFFER_SIZE, &length, buffer); // Ask OpenGL to give us the log associated with the program
    if (length > 0) // If we have any information to display
        cout << "Program " << program << " link error: " << buffer << endl; // Output the information
   
    glValidateProgram(program); // Get OpenGL to try validating the program
    GLint status;
    glGetProgramiv(program, GL_VALIDATE_STATUS, &status); // Find out if the shader program validated correctly
    if (status == GL_FALSE) // If there was a problem validating
cout << "Error validating shader " << program << endl; // Output which program had the error
}

Shader::Shader()
{
}

Shader::Shader(const std::string& vsFile, const std::string& fsFile)
{
inited = false;
init(vsFile, fsFile);
}

void Shader::init(const std::string& vsFile, const std::string& fsFile)
{
if(inited){ return; }
inited = true;

shader_vp = glCreateShader(GL_VERTEX_SHADER);
shader_fp = glCreateShader(GL_FRAGMENT_SHADER);

string vsText = textFileRead(vsFile);
string fsText = textFileRead(fsFile);

const char* vertexText = vsText.c_str();
const char* fragmentText = fsText.c_str();

if(!vertexText || !fragmentText)
{
cout << "Either vertex shader or fragment shader file not found." << endl;
return;
}

glShaderSource(shader_vp, 1, &vertexText, 0);
glCompileShader(shader_vp);
validateShader(shader_vp, vsFile);

glShaderSource(shader_fp, 1, &fragmentText, 0);
glCompileShader(shader_fp);
validateShader(shader_fp, fsFile);

shader_id = glCreateProgram();
glAttachShader(shader_id, shader_vp);
glAttachShader(shader_id, shader_fp);

glBindAttribLocation(shader_id, 0, "in_Position");
glBindAttribLocation(shader_id, 1, "in_Color");

glLinkProgram(shader_id);
validateProgram(shader_id);
}

Shader::~Shader()
{
glDetachShader(shader_id, shader_vp);
glDetachShader(shader_id, shader_fp);

glDeleteShader(shader_vp);
glDeleteShader(shader_fp);
glDeleteProgram(shader_id);
}

void Shader::bind()
{
glUseProgram(shader_id);
}

void Shader::unbind()
{
glUseProgram(0);
}



the error is here : shader_vp = glCreateShader(GL_VERTEX_SHADER);
with the error
Unhandled exception at 0x00000000 in opengl 4 sfml2.exe: 0xC0000005: Access violation.

please, help me ^^
tahnks to all.
and nice forum
Best Regards
    Davide Galli

* - junior c# programmer
* - base c++/opengl programmer
* - near having a motorbike.

moonshadow

  • Newbie
  • *
  • Posts: 2
    • View Profile
Similar Error with minimal Example
« Reply #1 on: June 22, 2011, 11:09:08 pm »
I have a similar problem on Ubuntu 11.04 with SFML2, OpenGL 3.3.0 NVIDIA 270.41.06 (nvidia-current restricted driver), with a Segmentation Fault on glCreateShader. In the GLEW header, this seems to some kind of function pointer, which is NULL. Messing around with some of my code and the opengl example, i was able to reduce to this:

Code: [Select]

#include <GL/glew.h>
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL", sf::Style::Default, sf::ContextSettings(32));

    sf::Image backgroundImage;
    backgroundImage.LoadFromFile("resources/background.jpg"); //comment out to get segfault
   
    GLuint vertex_shader;
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);

    return EXIT_SUCCESS;
}


It seems that some OpenGL/GLEW initialisation is unclean - there is a segfault when the marked piece of code is commented out. Of course, you need to have some backround.jpg in working-directory/resources.

Is this just something I'll have to work around in SFML2/Go back to SFML 1.6 for, or has someone had this kind of problem before?[/code]

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sfml2, opengl3.2 and glCreateShader
« Reply #2 on: June 22, 2011, 11:16:14 pm »
Quote
It seems that some OpenGL/GLEW initialisation is unclean

Indeed
Code: [Select]
glewInit();
Laurent Gomila - SFML developer

moonshadow

  • Newbie
  • *
  • Posts: 2
    • View Profile
sfml2, opengl3.2 and glCreateShader
« Reply #3 on: June 22, 2011, 11:27:17 pm »
Ouch! Thanks :(

And I was messing about with GlResource::EnsureGlContext. I hope it counts as some kind of excuse that it wasn't neccessary in 1.6, the same code was working perfectly then. Can it be that 1.6 did a glewInit()?

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
sfml2, opengl3.2 and glCreateShader
« Reply #4 on: June 22, 2011, 11:47:48 pm »
SFML2 does a glewInit too I think, it at least got a function to ensure it is.

In my game engine I do a custom call to glewInit in my renderer which is created per-context to get it to work.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
sfml2, opengl3.2 and glCreateShader
« Reply #5 on: June 23, 2011, 12:14:41 am »
GLEW is only an implementation detail of SFML, don't rely on it and use GLEW as if it was not used in SFML at all.
Laurent Gomila - SFML developer