A noob graphics / openGL question w.r.t. drawing the first triangle in the XY plane. As I understand the vertices need to be specified in counter clockwise order so that the normal is along the Z direction and will therefore be rendered by default. The question I have is whether there is a way one can specify the 3 vertices in any order but specify the normal attribute separately to accomplish this ?
As long as "Face Culling" is not enabled, the winding order is irrelevant. See OpenGL wiki - Face Culling. The normal vector is only important for the light model.
Face Culling has nothing to do with the normal vector. The faces are culled depending on the winding order of the vertices projected on the the view port.
If you have a triangle (A, B, C) and the normal vector N of this triangle, you can test that the points are ordered counterclockwise with respect to the normal vector with dot(cross(B-A, C-A), N) > 0. This does not mean that the face is also counterclockwise in the projection on the viewport. The winding order of the face in the viewport depends on how you are looking at the face.
If all faces of a closed volume have the same winding order, this can be used for Back Face Culling. Triangles viewed from the front retain the winding order in the projection, but triangles viewed from the back have the reverse winding order when projected.
the default setting for glFrontFace is counter clockwise and if you want to set it to clockwise you can use
glEnable(GL_CULL_FACE); //so you can see the diffirence
glFrontFace(GL_CW); //clockwise
glFrontFace(GL_CCW); //counter-clockwise
The setting for glFrontFace determines if the triangle is facing the camera or not so the triangle won't be visible to the camera (it won't be textured or colored).
Related
I am using OpenGl ES to visualize a mesh which has polygons with more than 3 vertexes. I wanted to convert these polygons to triangles using following loop. In the loop I created polygonVertexSize-2 number of triangles just by filling an OpenGL index array which refers to same vertexes in a different order and times.
for(int j=0;j<polygonVertexSize-2;j++) //number of triangles
{
//GetPolygonVertex returns the index of a polygon Vertex
indices[indp+0]=Polygon->GetPolygonVertex(0);
indices[indp+1]=Polygon->GetPolygonVertex(1+j);
indices[indp+2]=Polygon->GetPolygonVertex(2+j);
indp+=3;
}
Problem with this conversion is, unless I apply glDisable(GL_CULL_FACE) some parts of the meshes are not visible. Which probably means my triangulation cause surface normals to be wrong. Another thing to note is, I average a normal for a vertex using the normals of the same vertex in different triangles.
How may I solve this problem? is it a bad idea to disable culling to solve this problem?
Here are the results with culling and without
The problem is with back-face culling.
Part of the mesh are invisible because they are facing away from camera. glDisable(GL_CULL_FACE) is the simplest way to solve this problem but this can cause performance problems (every triangle is processed twice). But it shouldn't affect your scene.
If you want to do it "right" you have to change the winding for invisible triangles. Just swap two vertices.
//only for invisible triangles
indices[indp+0]=Polygon->GetPolygonVertex(0);
indices[indp+1]=Polygon->GetPolygonVertex(2+j);
indices[indp+2]=Polygon->GetPolygonVertex(1+j);
Your triangulation is right if your polygon is planar and convex. You can simply check if your polygon is convex using gift wrapping algorithm or just walk through vertices and compute dot products, if the sign of dot product changes, polygon is not convex
In back face culling you may either use the face normals to see if the face is pointing away from the camera of you may do some technique with if the triangle is drawn clock wise or counter clock wise.
I am confused about this technique with the clockwise. It seems like with this method, the ordering of the vertex data that gets sent to the graphics card decides whether it is facing towards or away from the camera. I don't see how this makes sense because the camera can be looking in any direction, it's as if the vertex data would have to change based on the camera position and that is obviously not done on the CPU.
How can I understand this?
This is one triangle viewed from opposite sides:
3 points in 3D space are defining a triangle. In addition, if those points are ordered (like here) they are also determining two sides (faces) of a triangle : clockwise and counter-clockwise (they are determined by the order clock put inside a face would point its vertices)
In above example triangle is textured counter-clockwise
Now imagine this triangle is an element of a dice:
If you roll the dice (or rotate camera around it) our triangle from CCW becomes CW and we don't want it to be textured any more.
This dice would be in fact built out of 12 such triangles and if we order them properly we will be texturing only 6 that are facing camera at a time.
I'll show you this on an example quad:
(0,0)-------(1,0)
| |
| X |
| |
(0,1)-------(1,1)
Let's assume we are starting at (0,0). Now, if you wind-up (pass) the vertices in "clockwise" order, the next ones would be (1,0), (1,1) and (0,1). (1,0) lays more or less on 2 o'clock, (1,1) is 4, and so on.
Thus the data in GPU memory: 0,0, 1,0, 1,1, 0,1.
When you correlate the windup direction with your setting, you can easily distinguish what's "front" and "back" - to imagine that better, you could draw it on something transparent, then look from the other side - the wind-up direction would be reversed.
So the specification of wind-up direction is merely to tell the GPU which side is front, and which one is back, as it cannot do it by itself - both sides of a triangle are equally good, and the normal vector of given polygon can either be N or -N. However, GPU can verify which of them is aligned with proper wind-up order.
Chapter 2 of The (Old) Red Book has some nice explanation regarding OpenGL specific stuff, that's still pretty relevant today.
That's exactly the point: the vertices order doesn't have to do with camera orientation initially, when you create/draw the face! Note that a camera is merely a transform, not something by itself recognized by openGL.
So, when rendering, after you'll have 'watched' through the camera, openGL simply checks (if culling is enabled) the new order of the face vertices, now according to the new orientation (after all transformations have been applied), to display the face or not.
If I've got 4 vertices which I render in this order:
2-3
|\|
0-1
using GL_TRIANGLE_STRIP and then I enable back-face culling with the front face defined as CCW, then would the bottom-left triangle be facing me and the other one not? If so, what's the most efficient way of rendering a square so that both faces are visible? Do I have to use GL_TRIANGLES and pass down 6 vertices instead of 4?
The strip primitive does the right thing with respect to backface culling. You can think of the tris' winding order as being managed so that the order is consistent for each triangle in the strip - e.g. you can think of the GPU rendering (0,1,2), (2,1,3) ...
All triangles in triangle strip maintain same direction/winding order.
They don't flip one after another. So either both triangles will be towards you or away from you (assuming your primitive is flat square shape (that is convex and doesn't intersect itself) where all vertices belong to same plane).
P.S. You know, you COULD render trianglestrip primitive in OpenGL application with culling enabled and see for yourself.
I've drawn a simple quad with glBegin and glEnd. With a for-loop I create copies of the quad and rotate it around my y-Axis in 3D space.
Now the problem is that I only see the quads in the front. These in the back are not displayed. I assume that the problem lies within the normal vector, which direction is towards me. Is there a possibility to define two normal vectors for one quad.
Sounds like you need to disable backface culling:
glDisable(GL_CULL_FACE);
These in the back are not displayed. I assume that th problem lies within the normal-vector,
The problem is not the normal vector, but what OpenGL considers front side and backside. What's what is determined by the winding of the vertices on the screen. If the vertices are on screen in counterclockwise order, then by default OpenGL assumes the front face. If back face culling is enables, back faces will not be drawn. You can disable culling, but then you'll get odd lighting results.
The best way is to draw the back side explicitly with it's own set of quads; windings and normals adjusted.
just a quick question. I have a quad in 3D OpenGL scene. I define a normal to the plane counter clockwise. So that the normal points out one side of the plane. In the direction of my light source. The quad is light but on both sides.
Should it not only be light on one side of the quad? Or is it the fact that a primitive like a quad is finitely thin and thus looks light from both sides. So if i wanted to make a wall I would use two quads. One for each side of the wall.
Thanks
The default OpenGL lighting behavior for two sided polygons is to calculate lighting for the front face and apply it to both sides.
You can get around this by using a front and back polygon with seperate normals for each of your double sided polygons.
Alternatively, you can enable GL_LIGHT_MODEL_TWO_SIDE for lighting calculations using glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE) . See the glLightModel reference for more information.