OpenGL & GLSL

Started by
9 comments, last by Simopi 14 years, 2 months ago
Hi, i'm new in GLSL. After so many search about bump mapping i don't understand what is the way to have a correct rendering. Because i don't know very well how GLSL works, and the math of the normals too :P I compute normals in this way:
 Vec3f a, b;
  a = Vector3Offset(v3, v2);
  b = Vector3Offset(v1, v2);

  Vec3f normal = a^b; //cross product 
Where Vector3Offset is v3-v2 and v1-v2. Then i compute tangents and binormals. Btw it seems normals are wrong. If i understand well, gl_Normal variable (in GLSL) contains the normal. To have it, i must call:
  
glEnableVertexAttribArrayARB(2);
glVertexAttribPointerARB(2, 3, GL_FLOAT, false, 0, normalsArray); 
Is that right? Thanks for your time, and sorry for my english.
Advertisement
What GLSL version are you targeting?

If you want to use gl_Normal, supply normals through glNormalPointer, not glVertexAttribPointer.
gl_Vertex, gl_Normal etc are deprecated functionality and I suggest you don't use them at all. The correct way to use glVertexAttribPointer with opengl 2.0+ would be to first extract the position of your normal attribute from the shader. Don't assume that the normal will be at a specific index as you have done here (you assume it will be at index 2, ie the third attribute in your shader).

For example, if your shader looks like this:
attribute vec4 Vertex;  // Input vertex declared as "Vertex"attribute vec3 Normal;  // Input normal declared as "Normal"varying vec3 v_normal;  // output normalvoid main(){  gl_Position = Vertex; // Output untransformed vertex  v_normal = Normal; // Pass on normal to fragment shader}


Then you would want to setup your attributepointers as such:
// This fetches the attribute indices from the shader.// the string "Vertex" and "Normal" matches the attributes// declared in the shaderGLint vertex_index = glGetAttribLocation(program, "Vertex");GLint normal_index = glGetAttribLocation(program, "Normal");// Need to calculate the stride of a complete vertex// in this case, two float3 (24 bytes)GLuint stride = sizeof(GLfloat)*3 + sizeof(GLfloat)*3; glEnableVertexAttribArray(vertex_index);glVertexAttribPointer(vertex_index, 3, GL_FLOAT, false, stride, vertexArray);glEnableVertexAttribArray(normal_index);glVertexAttribPointer(normal_index, 3, GL_FLOAT, false, stride, normalsArray);


Also, make sure you normalize your normals after that cross product ;)
Quote:Original post by Simopi
Vec3f normal = a^b; //cross product


Anyone else thing this looks wrong and should be:

Vec3f normal = cross(a, b); // cross product
@HuntsMan I use GLSL 1.5, this is the answer from the glGetString(GL_SHADING_LANGUAGE_VERSION).

Thanks for the answers, i'll try to apply your suggestions and i'll post here my progress ^_^
Hi guys, now i can see the model with bump mapping. Thanks for the suggestions. But there is something wrong. Again...
Here the rendering:
Click

What's wrong?
Hard to tell. Kind of looks like your vertex indices are slightly off. If you are using indexed vertices that is.

How does your vertex layout look? And how does your drawcall look?
Ok, i try to explain my work:

i use vertex arrays to render the 3ds object. If i don't use shader, the model seems ok. The problem is when i use the shader.

OpenGL source:

I compute the normals in this way:

 Vec3f triangle = obj->getShape().triangle.at(k);//Triangle vertices  Vec3f v1 = obj->getShape().vertex.at(triangle.i1);  Vec3f v2 = obj->getShape().vertex.at(triangle.i2);  Vec3f v3 = obj->getShape().vertex.at(triangle.i3);  Vec3f a, b;  a = v3-v2;  b = v1-v2;  Vec3f normal = a^b; //cross product//Texture coordinates  Vec2f st1 = obj->getShape().texture.at(triangle.i1);  Vec2f st2 = obj->getShape().texture.at(triangle.i2);  Vec2f st3 = obj->getShape().texture.at(triangle.i3);  Vec2f c, d;  c = st3-st2;  d = st1-st2;    float coef = 1/ (c.x * d.y - d.x * c.y);  Vec3f tangent;  tangent.x = coef * ((v1.x * d.y) + (v2.x * -c.y));  tangent.y = coef * ((v1.y * d.y) + (v2.y * -c.y));  tangent.z = coef * ((v1.z * d.y) + (v2.z * -c.y));  tangent.normalize();  normal.normalize();  Vec3f binormal = tangent^normal; //cross product  


Then i put everything into an array. For example, the normal array will be:

  normalArray[i++] = normal.x;  normalArray[i++] = normal.y;  normalArray[i++] = normal.z;


Then i call glNormalArray(... normalArray);

For tangents and binormals i use vertex attributes, declared into shader:

  attribute vec3 tangent;


and in opengl i call glVertexAttribPointer(...);

To render the vertices:

glDrawElements(GL_TRIANGLES, shape.triangle.size()*3, GL_UNSIGNED_SHORT, indexPointer); 


Thanks for the patience!

[Edited by - Simopi on February 18, 2010 1:26:22 PM]
is attribute supported in GLSL 1.5? Try with in and out and see if it works. And check with glBindAttribLocation instead of glGetAttribLocation.
Quote:Original post by Simopi
@HuntsMan I use GLSL 1.5, this is the answer from the glGetString(GL_SHADING_LANGUAGE_VERSION).

[smile][smile][smile] [grin]
HuntsMan asked you what GLSL version you're targeting, not what is the supported version!
The correct answer you can get if you find directive #version in the beginning of your shaders. If there is no #version directive, you are writing shaders for GLSL 1.1! Fortunately, NVIDIA enables mixing all versions of GLSL (as well as Cg).

Before going to further GLSL programming, I strongly recommend to read few beginning chapters from the "Orange book", or some good tutorial.

This topic is closed to new replies.

Advertisement