|
Setting a glsl shader attribute |
Vishiano
Member #12,652
March 2011
|
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? 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
Member #261
April 2000
|
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
Member #12,652
March 2011
|
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
Member #261
April 2000
|
The shader addon isn't going to add any overhead.. but anyway, here's some code from it that sets an attribute: 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
Member #12,652
March 2011
|
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? 1 glUseProgram(myShader);
2 glBegin(GL_POINTS);
3 {
4 glVertexAttrib4f(0, 0, 300, -740, 1);
5 }
|
Trent Gamblin
Member #261
April 2000
|
No. You set up color and vertex position arrays just like the texture arrays in the sample above, then you call glDrawArrays.
|
Vishiano
Member #12,652
March 2011
|
Mmmm, still having some trouble. Could you let me know which lines I should change or delete or are just useless? 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
Member #261
April 2000
|
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
Member #12,652
March 2011
|
Fixed the stride, but for glVertexAttrib pointer I binded 0 and 1 like so... glBindAttribLocation(myShader, 0, "vVertex"); so shouldn't 0 and 1 work for glVertexAttribPointer? Either way, still not getting my shader to appear. |
Trent Gamblin
Member #261
April 2000
|
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
Member #12,652
March 2011
|
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. |
|