0

I am working on adding a phong shader to my working program. After I implemented my new shaders, my code got a "Segmentation Fault: 11" during:

glDrawArrays(GL_TRIANGLES, 0, mCubes.getArrayNumberOfElements());

I know the number of elements is correct because it worked for my previous, simple shader.

Here is my Vertex Shader:

// vertex shader
attribute vec4 vPosition;
attribute vec3 vNormal;
varying vec4 color; //vertex shader
// light and material properties
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct; 
uniform mat4 ModelView;
//uniform mat4 Projection;
uniform vec4 LightPosition;
uniform float Shininess;
vec3 L, H, N, pos, E;
vec4 diffuse, specular, ambient;
float Kd, Ks;

void main()
{
    // Transform vertex position into eye coordinates 
    pos = (ModelView * vPosition).xyz; 
    L = normalize( LightPosition.xyz - pos ); 
    E = normalize( -pos );
    H = normalize( L + E );
    // Transform vertex normal into eye coordinates
    N = normalize( ModelView*vec4(vNormal, 0.0) ).xyz;
    // Compute terms in the illumination equation 
    ambient = AmbientProduct;
    Kd = max( dot(L, N), 0.0 );
    diffuse = Kd*DiffuseProduct;
    Ks = pow( max(dot(N, H), 0.0), Shininess );
    specular = Ks * SpecularProduct;
    if( dot(L, N) < 0.0 ) 
    specular = vec4(0.0, 0.0, 0.0, 1.0); 
    
    gl_Position = ModelView * vPosition;
    color = ambient + diffuse + specular;
    color.a = 1.0; 
}

Here is my display function in which the code ends up getting the fault:

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    vector<float> cell = mCubes.getCell();

    mat4 matrix = rot * scale(1.0/cell[0], 1.0/cell[1], 1.0/cell[2]) * translate(-cell[0]/2.0, -cell[1]/2.0, -cell[2]/2.0);
    glUniformMatrix4fv(vShaderModelView, 1, GL_TRUE, matrix);
    glDrawArrays(GL_TRIANGLES, 0, mCubes.getArrayNumberOfElements()); 
    glutSwapBuffers();
    glFlush();
}

And here is my init function that mostly sets up and interacts with the shaders:

void init() {
    // Create a vertex array object
    GLuint vao;
    #ifdef __APPLE__
    glGenVertexArraysAPPLE( 1, &vao );
    glBindVertexArrayAPPLE( vao );
    #else
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    #endif
    
    // Create and initialize a buffer object
    GLuint buffer;
   
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData( GL_ARRAY_BUFFER,
                 mCubes.getDisplayArraySize() + mCubes.getDisplayArraySize()*3,                NULL, GL_STATIC_DRAW );
    GLintptr offset = 0;
    glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getDisplayArray());
    offset+= mCubes.getDisplayArraySize();
    
    glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getNormalVector());

    // Load shaders and use the resulting shader program
    string evname = "PROTCAD3DIR";
    string path = PCGeneralIO::getEnvironmentVariable(evname);

    path += "/data/shaders/";
    #ifdef __APPLE__
    string vshadername = path + "kw_vshader1_mac.glsl";
    string fshadername = path + "kw_fshader1_mac.glsl";
    //#else
    //  string vshadername = path + "kw_vshader1.glsl";
    //  string fshadername = path + "kw_fshader1.glsl";
    #endif

    GLuint program = InitShader( vshadername.c_str(), fshadername.c_str() );

    glUseProgram(program);
    // Initialize the vertex position attribute from the vertex shader    
    GLuint vShaderPosition = glGetAttribLocation(program, "vPosition");
    glEnableVertexAttribArray(vShaderPosition);
    glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    GLuint vShaderNormal = glGetAttribLocation(program, "vNormal");
    glEnableVertexAttribArray(vShaderNormal);
    //glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset)); //this was the ORIGINAL PROBLEM, now commented out and below is solution
      glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
   
    
    vShaderModelView = glGetUniformLocation(program, "ModelView");
    vShaderLightPosition = glGetUniformLocation(program, "LightPosition");
    
    vShaderAmbientProduct = glGetUniformLocation(program, "AmbientProduct");
    vShaderDiffuseProduct = glGetUniformLocation(program, "DiffuseProduct");
    vShaderSpecularProduct = glGetUniformLocation(program, "SpecularProduct");
    vShaderShininess = glGetUniformLocation(program, "SpecularProduct");
    glEnable( GL_DEPTH_TEST );
    
    vec4 light = vec4(0.5,1.5,1.0,0.0);
    glUniform4fv(vShaderLightPosition, 1, light);
    vec4 amb = vec4(1.0f,0.0f,0.20f,1.0f);
    glUniform4fv(vShaderAmbientProduct, 1, amb);
    vec4 diff = vec4(0.5f,0.5f,0.5f,1.0f);
    glUniform4fv(vShaderDiffuseProduct, 1, diff);
    vec4 spec = vec4(0.80f,0.80f,0.80f,1.0f);
    glUniform4fv(vShaderSpecularProduct, 1, spec);
    float shin = 6.0f;
    glUniform1f(vShaderShininess,shin);
     
    glClearColor(.2, .2, .2, 1); /* Grey background */
}

If you have any questions, feel free to ask and I will elaborate. I feel that either the vertex shader itself has a problem, or the way I interact with the shader is doing something wonky. Any help or suggestions are accepted!

EDIT::: (code edited to reflect solution) The problem was in the second:

glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));

which should have read:

glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));

And was a stupid copy/paste mistake. However, the finished product still does not look correct:

At Rotation 0 it seems to be fully colored:

at Rotation 0 it seems to be fully colored

Rotation of a little bit reveals some odd behavior:

Rotation of a little bit reveals some odd behavior

Even more rotation leads you to pull your hair out:

Even more rotation leads you to pull your hair out

Then it whites out and you know I screwed up!!

Then it whites out and you know I screwed up!!

So, as you rotate the color gets screwed up and turns white, black, patterned and everything, but this is obviously incorrect.

Edit::: This is my attempt to "Correct" the issue of passing the wrong amount of values with vNormal:

void init() {
  // Create a vertex array object
  GLuint vao;
    #ifdef __APPLE__
    glGenVertexArraysAPPLE( 1, &vao );
    glBindVertexArrayAPPLE( vao );
    #else
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    #endif
  
    // Create and initialize a buffer object
    GLuint buffer;
    realVec *normArray = new realVec[mCubes.getNormalArraySize()];//vec4 array compared to vec3 array     
    normArray = mCubes.getNormalVector(); // new array of normals
    
    for(int i=0; i<mCubes.getArrayNumberOfElements();i++){
        printf("Normal at %d  is %f \n",i,normArray[i][0]); //to print normals
        printf("Normal at %d  is %f \n",i,normArray[i][1]); //to print normals
        printf("Normal at %d  is %f \n",i,normArray[i][2]); //to print normals
    }
   
  glGenBuffers(1, &buffer);
  glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData( GL_ARRAY_BUFFER,
                 mCubes.getDisplayArraySize() + mCubes.getNormalArraySize(),                NULL, GL_STATIC_DRAW ); //Changed size for vec3 array of normals
    GLintptr offset = 0;
  glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getDisplayArraySize(), mCubes.getDisplayArray());
    offset+= mCubes.getDisplayArraySize();
    
    glBufferSubData(GL_ARRAY_BUFFER, offset, mCubes.getNormalArraySize(), normArray);

    // Load shaders and use the resulting shader program
    string evname = "PROTCAD3DIR";
    string path = PCGeneralIO::getEnvironmentVariable(evname);

    path += "/data/shaders/";
    #ifdef __APPLE__
    string vshadername = path + "kw_vshader1_mac.glsl";
    string fshadername = path + "kw_fshader1_mac.glsl";
    //#else
    //  string vshadername = path + "kw_vshader1.glsl";
    //  string fshadername = path + "kw_fshader1.glsl";
    #endif

    GLuint program = InitShader( vshadername.c_str(), fshadername.c_str() );

  glUseProgram(program);
    //offset =0;
  // Initialize the vertex position attribute from the vertex shader    
  GLuint vShaderPosition = glGetAttribLocation(program, "vPosition");
  glEnableVertexAttribArray(vShaderPosition);
  glVertexAttribPointer(vShaderPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    GLuint vShaderNormal = glGetAttribLocation(program, "vNormal");
  glEnableVertexAttribArray(vShaderNormal);
  glVertexAttribPointer(vShaderNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));
    
   
  //vShaderMatrix = glGetUniformLocation(program, "vMatrix");
  //vShaderColor = glGetUniformLocation(program, "vColor")
    vShaderModelView = glGetUniformLocation(program, "ModelView");
    vShaderLightPosition = glGetUniformLocation(program, "LightPosition");
    //vShaderProjection = glGetUniformLocation(program, "Projection");
    
    vShaderAmbientProduct = glGetUniformLocation(program, "AmbientProduct");
    vShaderDiffuseProduct = glGetUniformLocation(program, "DiffuseProduct");
    vShaderSpecularProduct = glGetUniformLocation(program, "SpecularProduct");
    vShaderShininess = glGetUniformLocation(program, "SpecularProduct");
  glEnable( GL_DEPTH_TEST );
    
    vec4 light = vec4(0.5,1.5,1.0,0.0);
    glUniform4fv(vShaderLightPosition, 1, light);
    vec4 amb = vec4(1.0f,0.0f,0.20f,1.0f);
    glUniform4fv(vShaderAmbientProduct, 1, amb);
    vec4 diff = vec4(0.5f,0.5f,0.5f,1.0f);
    glUniform4fv(vShaderDiffuseProduct, 1, diff);
    vec4 spec = vec4(0.80f,0.80f,0.80f,1.0f);
    glUniform4fv(vShaderSpecularProduct, 1, spec);
    float shin = 6.0f;
    glUniform1f(vShaderShininess,shin);
    
    glClearColor(.2, .2, .2, 1); /* Grey background */
}

Should I maybe change the light, ambient, specular, and diffuse properties? I am not sure what the problem is.

4
  • Show us what is mCubes (what does its methods return). Commented Jan 20, 2012 at 21:30
  • mCubes is just another piece to a large puzzle of c++ classes. I cannot possibly show you all of them, but mCubes the calls to mCubes are pretty self explanatory. It either returns an Array of Verticies for triangles, or the size of the array of vertices, or the number of triangles(elements), or the Normals Vectors Array. Commented Jan 20, 2012 at 22:27
  • Could you update your code to include the correction you already found ? This will allow to follow the actual problem more easily. Commented Jan 20, 2012 at 22:53
  • Sure, and I will add a 'comment' in there that i was changed. Thanks for the suggestion. Commented Jan 20, 2012 at 22:54

1 Answer 1

1

You pass your vNormal attribute data using the following code

glVertexAttribPointer(vShaderNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset));

This indicates that your normal have 4 components, whereas in your vertex shader you declare it as

attribute vec3 vNormal;

This mismatch may be related to your problem if the normals are misinterpreted.

Sign up to request clarification or add additional context in comments.

6 Comments

Ironically, when I 'Correct' this issue, I get this: i.sstatic.net/eyjPv.png Which is an absence of any of the color!
Could you elaborate on how your 'corrected' this ? What is the actual memory layout of your normals ? Did you try to display the values given by vNormalin you fragment shader to 'see' if their are correct ?
I added a "corrected" init() function to the bottom. Didn't want to replace the other one so that people can follow along.
I fear the problem may lie in the Normals... I must admit I am not sure of the correct proper range of normal values, but I mostly get values of +-0.30###, +-0.90###, +-0.70###, 0.0, 1.0. I believe this to be incorrect, and will try to figure out if so or not.
Consider the possibility that your normals may be pointed 'in' instead of 'out' so you seeing only the backs of polygons, not the front faces that are colored and shaded.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.