Setting a glsl shader attribute
Vishiano

I'm working on a opengl graphics project using allegro 5 for school. I've been using the OpenGL superbible 5th ed as a guide, however I've run across a problem. The book uses GLTools to work with shaders for the majority of the book, but in chapter 12 it tries to explain how to load your own attributes without using GLTools. My issue is the examples are rather short and the book jumps to more advanced topics very quickly. I've copied/written code that should work, but I have no idea what my next step should be. Could someone look at my code below and point me in the right direction?

#SelectExpand
1 2 char *arg[] = {"vVertex", "vColor"}; 3 myShader = loadShaders("test_vertex.vp.txt", "test_vertex.fp.txt", arg, 2); 4 glUseProgram(myShader); 5 glGenVertexArrays(1, &vao);//generate the VAO!!! 6 glBindVertexArray(vao); //in the darkness BIND IT!! 7 8 glGenBuffers(1, &vbo); 9 glBindBuffer(GL_ARRAY_BUFFER, vbo); 10 11 static const GLfloat positions[] = {300, 200, -740, 1}; 12 static const GLfloat colors[] = {1, 1, 1,1}; 13 glBufferData(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(colors), NULL, GL_STATIC_DRAW); 14 glBufferSubData(GL_ARRAY_BUFFER, 0,sizeof(positions), positions); 15 glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions), sizeof(colors), colors); 16 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0,(const GLvoid *)0); 17 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0,(const GLvoid *)sizeof(positions)); 18 19 glEnableVertexAttribArray(0); 20 glEnableVertexAttribArray(1); 21 22 m_locMVP = glGetUniformLocation(starFieldShader, "mvpMatrix"); 23 m_locTexture = glGetUniformLocation(starFieldShader, "starImage"); 24 m_locTimeStamp = glGetUniformLocation(starFieldShader, "timeStamp"); 25 26 glGenTextures(1, &m_starTexture); 27 m_star = al_load_bitmap("star.tga"); 28 al_set_target_bitmap(m_star); 29 starTexture = al_get_opengl_texture(m_star); 30 if (m_starTexture != 0) 31 glBindTexture(GL_TEXTURE_2D, m_starTexture); 32 else 33 cout<<"get opengl texture FAIL";

Trent Gamblin

Google and OpenGL reference is your friend.

What you want is something like (this would be for the texture):

   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, starTexture);
   glUniform1i(m_locTexture, 0);

This is taken from the allegro_shader addon which is in the 5.1 branch of Allegro. You might want to have a look at it. Setting matrices and other uniforms is pretty easy too.

[edit]

Oops, I forgot to explain it. When you have a sampler2D in a shader it's not actually a texture number but a texture unit that it references. In the above code, you set the active texture unit to 0 (you can use more texture units for multitexturing if you want), bind the texture, then the glUniform call tells the shader that that sampler is using texture unit 0.

Vishiano

Didn't I already bind the texture and set its location? I'm aware that allegro 5.1 will add in shader support, and thats great, but I'm already pushing my professor's limits using Allegro for display/keyboard input.

Maybe I'm not explaining my confusion well enough. I'm pretty sure I've compiled and linked my shader code correctly. I'm also fairly certain I've set my uniforms correctly. I'm not certain I've set my attributes correctly, or how to draw using the shader(GlBegin??).

Trent Gamblin

The shader addon isn't going to add any overhead.. but anyway, here's some code from it that sets an attribute:

#SelectExpand
1 2bool _al_set_shader_texcoord_array_glsl(ALLEGRO_SHADER *shader, float *u, int stride) 3{ 4 ALLEGRO_SHADER_GLSL_S *gl_shader = (ALLEGRO_SHADER_GLSL_S *)shader; 5 6 GLint loc = glGetAttribLocation(gl_shader->program_object, "texcoord"); 7 if (loc < 0) 8 return false; 9 10 if (u == NULL) { 11 glDisableVertexAttribArray(loc); 12 return true; 13 } 14 15 glVertexAttribPointer(loc, 2, GL_FLOAT, false, stride, u); 16 glEnableVertexAttribArray(loc); 17 18 return true; 19}

"u" is a pointer to the first floating point texture coordinate and stride is the number of bytes between "u"s.

Vishiano

Thats a little helpful, I really cant use allegro shaders, but it does help a little. How would you draw that shader? Would something like this work?

#SelectExpand
1 glUseProgram(myShader); 2 glBegin(GL_POINTS); 3 { 4 glVertexAttrib4f(0, 0, 300, -740, 1); 5 }

Trent Gamblin

No. You set up color and vertex position arrays just like the texture arrays in the sample above, then you call glDrawArrays.

Vishiano

Mmmm, still having some trouble. Could you let me know which lines I should change or delete or are just useless?

#SelectExpand
1 char *arg[] = {"vVertex", "vColor"}; 2 myShader = loadShaders("test_vertex.vp.txt", "SpaceFlight.fp", arg, 2); 3 glUseProgram(myShader); 4 glGenVertexArrays(1, &vao);//generate the VAO!!! 5 glBindVertexArray(vao); //in the darkness BIND IT!! 6 7 glGenBuffers(1, &vbo); 8 glBindBuffer(GL_ARRAY_BUFFER, vbo); 9 10 static const GLfloat positions[] = {300, 200, -740, 1}; 11 static const GLfloat colors[] = {1, 1, 1,1}; 12 const float *u = &positions[0]; 13 const float *p = &colors[0]; 14 15 glBufferData(GL_ARRAY_BUFFER, sizeof(positions) + sizeof(colors), NULL, GL_STATIC_DRAW); 16 glBufferSubData(GL_ARRAY_BUFFER, 0,sizeof(positions), positions); 17 glBufferSubData(GL_ARRAY_BUFFER, sizeof(positions), sizeof(colors), colors); 18 19 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, u);//0 stride cuz its only one point? 20 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, p); 21 glEnableVertexAttribArray(0); 22 glEnableVertexAttribArray(1); 23 24 m_locMVP = glGetUniformLocation(myShader, "mvpMatrix"); 25 m_locTexture = glGetUniformLocation(myShader, "starImage"); 26 m_locTimeStamp = glGetUniformLocation(myShader, "timeStamp"); 27 28 glGenTextures(1, &m_starTexture); 29 m_star = al_load_bitmap("star.tga"); 30 al_set_target_bitmap(m_star); 31 starTexture = al_get_opengl_texture(m_star); 32 if (m_starTexture != 0) 33 glBindTexture(GL_TEXTURE_2D, m_starTexture); 34 else 35 cout<<"get opengl texture FAIL"; 36 37//then my render function looks like this 38void render_my_shader() 39{ 40 glEnable(GL_BLEND); 41 glBlendFunc(GL_ONE, GL_ONE); 42 43 // Let the vertex program determine the point size 44 glEnable(GL_PROGRAM_POINT_SIZE); 45 //glEnable(TEXTURE_2D); 46 47 // Bind to our shader, set uniforms 48 glUseProgram(myShader); 49 glUniformMatrix4fv(m_locMVP, 1, GL_FALSE, viewFrustum.GetProjectionMatrix()); 50 glUniform1i(m_locTexture, 0); 51// glEnableVertexAttribArray(0);//when these are uncommented I get an exception 52// glEnableVertexAttribArray(1); 53 54 float fTime = moveZ; 55 glUniform1f(m_locTimeStamp, fTime*5); 56 glBindTexture(GL_TEXTURE_2D, m_starTexture); 57 58glDrawArrays(GL_POINTS, 0, 1); 59 60}

Trent Gamblin

Didn't look at it all but stride should not be zero it should be sizeof(type)*num_components if they're tightly packed. Also passing 0 and 1 to glVertexAttribPointer is wrong, you are supposed to pass the value retrieved from getGetVertexAttribPointer (IIRC that's the name of the function but it might be something else).

Vishiano

Fixed the stride, but for glVertexAttrib pointer I binded 0 and 1 like so...

glBindAttribLocation(myShader, 0, "vVertex");
glBindAttribLocation(myShader, 1, "vColor");

so shouldn't 0 and 1 work for glVertexAttribPointer? Either way, still not getting my shader to appear.

Trent Gamblin

I don't know about that function. I also haven't used VBOs so I can't tell if that code is right. Are you sure you want to draw just 1 pixel?

Vishiano

Just trying to get the hang of setting up shaders, how many points I draw is arbitrary. If you know an easier way to do it I'm certainly open to that.

Thread #606878. Printed from Allegro.cc