0
votes

I am writing a basic view manager using GL on ubuntu 13 and eeepc with a nvidia ION2 (optimus in use using bumblebee project). I've an XML file from which shaders are created when the system starts (like plugins) and added to a dictionary. Once these are compiled and linked and ready for use, a wrapper function is used to select the appropriate shader program based on the program name passed.

void ShadingProgramManager::useProgram(const std::string& program){
    GLuint id = getProgramId(program);
    glUseProgram(id);
    if(GL_INVALID_VALUE == glGetError() || GL_INVALID_OPERATION == glGetError()){
        printf("Problem Loading Shader Program");
        return;
    }
    printf("%s is in use", program.c_str());
}

Where getProgramId simply looks inside the pre created dictionary and returns the id of the shader program.

When I render the object, I put the program to use by calling:

ShadingProgramManager::getInstance()->useProgram('vc');

'vc' is formed of the following shaders

Vertex Shader - vc.vert

#version 330
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
out vec4 vertcolor;
void main(){
    vertcolor = color;
    gl_Position = vec4(position, 1.0);   //I've tried setting this as position * 10 also for any apparent changes on screen, but nothing changes
}

Fragment Shader - vc.frag:

#version 330
in vec4 vertcolor;
out vec4 outputcolor;
void main(){
    outputcolor = vertcolor;
}

My vertex buffer is interleaved as:

VertexColor vertices[] = 
{
    {-1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0},  /*first 3 floats for pos, 4 for color */
    { 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0},
    { 1.0,  1.0, 0.0, 0.0, 1.0, 0.0, 1.0},
    {-1.0,  1.0, 0.0, 0.0, 0.0, 1.0, 1.0},
};

Index Buffer is as:

GLuint indices[] = 
{
    0, 1, 2,
    0, 2, 3,
};

VertexColor defined as:

class VertexColor{
    GLfloat x;
    GLfloat y;
    GLfloat z;
    GLfloat r;
    GLfloat g;
    GLfloat b;
    GLfloat a;
    /** some constants as below **/
};

const int VertexColor::OFFSET_POSITION =0;
const int VertexColor::OFFSET_COLOR =12;
const int VertexColor::SIZE_POSITION =3;
const int VertexColor::SIZE_COLOR =4;
const int VertexColor::STRIDE =28;

Then I use the following code to render the quad:

ShadingProgramManager::getInstance()->useProgram('vc');
glBindBuffer(GL_ARRAY_BUFFER, &vb);
glBufferData(GL_ARRAY_BUFFER, size_of_vertices_array, vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, &ib);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_of_indices_array, indices, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glVertexAttribArrayPointer(0, VertexColor::SIZE_POSITION, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_POSITION);
glVertexAttribArrayPointer(1, VertexColor::SIZE_COLOR, GL_FLOAT, GL_FALSE, VertexColor::STRIDE, (GLvoid*)VertexColor::OFFSET_COLOR);
glDrawElements(GL_TRIANGLES, size_of_indices, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

However, I only see a white quad. I suspect it's the fixed function pipeline that comes into effect.

Even if I remove the call to glUseProgram(id) or use glUseProgram(0), I'm still getting the same results. I also tried multiplying the position in the vertex shader by 10.0 but no effect on screen. I am sure that the shaders are being compiled and linked as well. When I change to use something like glUseProgram(40) or any invalid number, I get the requisite error messages but elsewise, I only see a white unit square!

Sorry for the obtrusively long post but I am stumped on this one...I just get a white unit square no matter what changes I do to the vert or frag shader. I suspect GL is defaulting to the FFP, and for some reason my shader program is not falling into effect. I am hoping it's a noobish mistake, but any pointers would be appreciated.

PS: There are no compile errors so please excuse any syntactical errors in the code. I've typed the complete code above.

UPDATE: I've added the last parameter in the call to glVertexAttribArrayPointer as suggested by Andon, Dinesh and Spektre, and I had missed earlier, but still same results.

2
Any GL errors? Does the shader actually compile? - thokra
well i try the GLSL code and it works... colors are changing ... of course you do not pass any transform matrix and also not performing any transform so do not expect to have anything moving or correct perspective ... just for the fun try to look on the GLSL logs via glGetShaderInfoLog(vert_id,_size,&siz,dat); PS. i did not use your VAO instead i use my 3D models ... it may be just the case your view is in the wrong place/direction - Spektre
oh and one last thing i see VertexColor is with 7 components what data allign do you use ... may be the compiler shift it to some power of 2 BYTE align and distort the info inside for VBO/VAO if that is the case use #pragma pack ... to solve it - Spektre
The final parameter in your call to glVertexAttribArrayPointer (...) is an offset from the base address of the VBO's data store. It should be (void *)0 for the first pointer in your VBO, something like (void *)sizeof (GLfloat)*<num_previous_components> for each following pointer. Using the stride instead of the proper offset is causing the VBO to reference the second vertex position in your VBO and both color and position start at this location. You are effectively short-changing your vertex buffer by 1 vertex. - Andon M. Coleman
Spektre, sure I ain't passing any transformation matrix but I have a ortho projection with a viewport set. And I am converting the vertex in the vs to homogenous by passing in w = 1.0. I tried multiplying the position with scalar 10 to affect the clip space coords within the vs. I was expecting to see some effect there. I will try to find out the POT byte alignment. Could you suggest any vertex pixel debugger that could help - girishsarwal

2 Answers

0
votes

Look at this line

glVertexAttribArrayPointer(1, VertexColor::SIZE_COLOR, GL_FLOAT, GL_FALSE, VertexColor::STRIDE);

Where is the pointer to Specifies a offset of the first component of the first generic vertex attribute in the array. In your vertex array color data starts at 4th position. You have to specify the starting position of first component of color data. Initial pointer value is 0 so program reads color data from first position to 4th position which is not color data. But it read vertex data correctly because program reads vertex data from first position to 3rd position which is correct value.That's way you see only white quad.

0
votes

Problem solved.

Yes, it was a noobish mistake, but all your comments helped me run through the entire code once again. I started off with redoing everything with the FFP and moving onto the PFP. So here is the error:

I missed putting in glAttachShader(pid, sid) in the dictionary that was being created for shader programs, so while the program was in effect, the vertex shader and the frag shader were never being applied.