UbunTom
UbunTom

Reputation: 405

OpenGL segfault when generating buffer

I am using uniform blocks and have encountered a problem when creating uniform buffers for them. The problem is that when generating a buffer in a certain place (as show in the 1st code sample, about 2/3 way down), a segfault occurs during glClear();

Interestingly the order of the glGenBuffers matters, as the segfault will not occur if I swap 2 calls to the function.

program.cpp:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <helpful.hpp> //Contains text read and shader loading functions


using namespace std;


int main(int args, char* argv[])
{
    //## Create context ##//
    unsigned int a;
    glfwInit();


    glfwWindowHint(GLFW_DEPTH_BITS,16);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

    GLFWwindow* window = glfwCreateWindow(1368, 768, "", NULL, NULL);

    glfwMakeContextCurrent(window);


    glewExperimental=GL_TRUE;
    glewInit();

    cout << "GL context created" << endl;

    a = glGetError();
    if (a!=0)cout << "Context error" << a << endl;

    glViewport(0, 0, 1368, 768);


    //## Setup shader ##//

    const char* vsText = textFileRead("shaders/testShader/shader.vert");    //Reads a text file
    const char* fsText = textFileRead("shaders/testShader/shader.frag");

    string vsource = "#version 140 \n";
    string fsource = "#version 140 \n";

    vsource += vsText;
    fsource += fsText;

    array<GLuint, 3> out = loadShaders("testShader",vsource,fsource);

    GLuint shader_id = out[0];
    GLuint shader_vp = out[1];
    GLuint shader_fp = out[2];

    glBindAttribLocation(shader_id, 0, "in_Vertex");
    glBindFragDataLocation(shader_id, 0, "out_Scene");

    glAttachShader(shader_id, shader_fp);
    glAttachShader(shader_id, shader_vp);
    glLinkProgram(shader_id);

    glUseProgram(shader_id);

    cout << "s : " << shader_id << endl;

    GLuint globalIndex = glGetUniformBlockIndex(shader_id, "GlobalSettings");
    glUniformBlockBinding(shader_id, globalIndex, 1);

    GLuint modelIndex = glGetUniformBlockIndex(shader_id, "ModelSettings");
    glUniformBlockBinding(shader_id, modelIndex, 2);


    //## Fill Uniform block buffers ##//

    float f[16] = {
        1.f,    .2f,    1.f,    .2f,
        1.f,    .2f,    1.f,    .2f,
        1.f,    .2f,    1.f,    .2f,
        1.f,    .2f,    1.f,    .6f,
    };

    GLuint subo; //"GlobalSettings" block
    glGenBuffers(1, &subo);
    glBindBuffer(GL_UNIFORM_BUFFER, subo);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 16, f, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, subo, 1);

    //This is what causes the error
    //Comment out these 2 lines and it works
    //Or swap this block with the one below
    GLuint b;
    glGenBuffers(1, &b);

    GLuint mubo; //"ModelSettings" block
    glGenBuffers(1, &mubo);
    glBindBuffer(GL_UNIFORM_BUFFER, mubo);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 16, f, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, mubo, 2);





    //## Create a simple quad to draw on screen ##//
    GLuint vao;
    GLuint vbo;
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);

    std::vector<glm::vec3> v;

    v.push_back(glm::vec3(-1.,-1.,0));
    v.push_back(glm::vec3(1.,-1.,0));
    v.push_back(glm::vec3(1.,1.,0));
    v.push_back(glm::vec3(-1.,-1.,0));
    v.push_back(glm::vec3(1.,1.,0));
    v.push_back(glm::vec3(-1.,1.,0));

    glBindVertexArray(vao);

    glEnableVertexAttribArray(0);

    int numVertices = v.size();
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(GLfloat) * 3, v.data(), GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindVertexArray(0);

    glfwPollEvents();

    glClearColor(0.2,0.2,0.2,1);
    while (true)
    {
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        glBindVertexArray(vao);
        glUseProgram(shader_id);
        glDrawArrays(GL_TRIANGLES, 0, numVertices);
        glBindVertexArray(0);

        glfwSwapBuffers(window);
    }

}

Here are the shaders:

Vertex:

layout( std140 ) uniform GlobalSettings {
    mat4 projectionMatrix;
};

layout( std140 ) uniform ModelSettings {
    mat4 MVMatrix;
};

in vec3 in_Vertex;
in vec3 in_Normal;

out vec4 eyePosition;
out vec4 screenPosition;

out vec3 pass_Normal;

void main(void)
{
    vec4 vertex=vec4(in_Vertex, 1.0);

    eyePosition = MVMatrix * vertex;

    screenPosition = gl_Position = vertex;

    pass_Normal = in_Normal;

}

Fragment

layout( std140 ) uniform GlobalSettings {
    mat4 projectionMatrix;
};

layout( std140 ) uniform ModelSettings {
    mat4 MVMatrix;
};


in vec4 screenPosition;
in vec4 eyePosition;
in vec3 pass_Normal;
out vec4 out_Scene;

void main(void)
{   
    float d = dot(normalize(pass_Normal), vec3(0,0,-1));
    float a = 1;
    //if(d>0)a=1;
    out_Scene = vec4(MVMatrix[3][1],MVMatrix[3][2],MVMatrix[3][3],a);
}

The shader loading function can be found here http://pastebin.com/XqewS28W in needed.

Upvotes: 0

Views: 762

Answers (1)

UbunTom
UbunTom

Reputation: 405

The problem is that the parameters in glBindBufferBase are the wrong way around, thus the index argument was being given a buffer name and vice versa. It only worked by coincidence as the buffer names happened to be the same as the indices, and generating in the extra buffer resulted in the indices no longer matching the buffers.

Upvotes: 2

Related Questions