2013-10-19 49 views
0

我正在使用統一塊並在爲它們創建統一緩衝區時遇到問題。問題是,當在某個地方生成一個緩衝區時(如第一代碼示例中所示,大約2/3向下),glClear()期間發生段錯誤。生成緩衝區時出現OpenGL段錯誤

有趣的是,glGenBuffers的順序很重要,因爲如果將2次調用交換到函數,segfault不會發生。

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); 
    } 

} 

這裏是着色器:

頂點:

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; 

} 

片段

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); 
} 

着色器加載功能可以在這裏找到需要。

+0

只使用調試器 – Drop

+0

如果只是這樣簡單。 – UbunTom

+0

原來,它甚至比那更簡單:) – UbunTom

回答

2

問題是,glBindBufferBase中的參數是錯誤的方式,因此索引參數被賦予一個緩衝區名稱,反之亦然。它只是巧合地工作,因爲緩衝區名稱碰巧與索引相同,並且在額外緩衝區中生成導致索引不再匹配緩衝區。