Jump to content
  • Advertisement
Sign in to follow this  
Aumnayan

OpenGL Normal Calculations

This topic is 2237 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on various aspects of shading and am experiencing some results that I didn't expect. Right now, I just want to eliminate the normals as the potential cause, however since I'm fairly new to openGL I'm having a hard time doing this with any amount of certanty.

If someone is willing to take a look at my normal generation code and give me their oppinion/point out problems, I would appreciate it.

The verts are stored in one large VBO at the moment, then drawn through a glDrawRangeElements call using GL_TRIANGLES. I'm unsure if/how the order matters, however the triangles and their verts are arranged in the following order:

triangle_1 = v1, v2, v0
triangle_2 = v2, v3, v0
triangle_3 = v3, v4, v0
triangle_4 = v4, v1, v0

[source lang="cpp"]void build_TriNormals (SVN_TERRAIN_VERTEX *svnVerts, int svnStride)
{
int i, j, k;
SVN_TERRAIN_VERTEX *v[6];

for (i = 0; i < svnStride; i++) {
for (j = 0; j < svnStride; j++) {
// v2
// |
// v1 - v0 - v3
// |
// v4

v[0] = &svnVerts[(i * svnStride) + j];

if (v[0]) {
v[1] = (!j) ? NULL: v[0] - 1;
v[2] = (i == svnStride - 1) ? NULL: v[0] + svnStride;
v[3] = (j == svnStride - 1) ? NULL: v[0] + 1;
v[4] = (!i) ? NULL: v[0] - svnStride;
v[5] = v[1];

SVN_VEC3 normal;
memset((char*) &normal, 0, sizeof(SVN_VEC3));

for (k = 1; k < 5; k++) {
if (v[k] && v[k + 1]) {
SVN_VEC3 obj1, obj2;

obj1 = subVec3((SVN_VEC3*) v[k], (SVN_VEC3*) v[0]);
obj2 = subVec3((SVN_VEC3*) v[k + 1], (SVN_VEC3*) v[0]);

obj1 = crossVec3(&obj1, &obj2);
normal = addVec3(&normal, &obj1);
}
}

normal = normalizeVec3(&normal);
v[0]->Xnorm = normal.x;
v[0]->Ynorm = normal.y;
v[0]->Znorm = normal.z;
}
}
}
}

SVN_VEC3 normalizeVec3(SVN_VEC3* vec)
{
SVN_VEC3 retVal;
float length;

length = sqrt(pow(vec->x, 2) + pow(vec->y, 2) + pow(vec->z, 2));
retVal.x = vec->x / length;
retVal.y = vec->y / length;
retVal.z = vec->z / length;

return retVal;
}

SVN_VEC3 crossVec3(SVN_VEC3 *left, SVN_VEC3 *right)
{
SVN_VEC3 retVal;

retVal.x = (left->y * right->z) - (left->z * right->y);
retVal.y = (left->z * right->x) - (left->x * right->z);
retVal.z = (left->x * right->y) - (left->y * right->x);

return retVal;
}

SVN_VEC3 crossVec3(SVN_VEC3 *left, SVN_VEC3 *right)
{
SVN_VEC3 retVal;

retVal.x = (left->y * right->z) - (left->z * right->y);
retVal.y = (left->z * right->x) - (left->x * right->z);
retVal.z = (left->x * right->y) - (left->y * right->x);

return retVal;
}[/source]

Share this post


Link to post
Share on other sites
Advertisement
Aside from major performance issues, there is nothing wrong with the vector math itself.
However your normal calculation is wrong.
obj1 should be normalized before being added to normal.


L. Spiro

Share this post


Link to post
Share on other sites
Thanks L. Spiro, that is what I was looking for. This is primarily a tool to help me learn the in's and outs of opengl, so I'm not horrible concerned with performance, which I can come back to if it ever envolves into something more then a science experiment.

To be clear, that particular bit should read:

[source lang="cpp"].
.
.

obj1 = crossVec3(&obj1, &obj2);
obj1 = normalizeVec3(&obj1);
normal = addVec3(&normal, &obj1);
}
}

normal = normalizeVec3(&normal);
.
.
.[/source]

correct?

Share this post


Link to post
Share on other sites

correct?

Does it give correct results?
You never explained or provided screenshots of the problem you were experiencing.


L. Spiro

Share this post


Link to post
Share on other sites
I apologize. After I made the changes you suggested, my scene now looks like:

UoGzCAd.jpg

There are still several areas to work on, but I don't believe what's remaining has to do with the normal calculations. I appreciate you're help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!