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.
Related
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).
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
So when drawing a rectangle on OpenGL, if you give the corners of the rectangle texture coordinates of (0,0), (1,0), (1,1) and (0, 1), you'll get the standard rectangle.
However, if you turn it into something that's not rectangular, you'll get a weird stretching effect. Just like the following:
I saw from this page below that this can be fixed, but the solution given is only for trapezoidal values only. Also, I have to be doing this over many rectangles.
And so, the questions is, what is the proper way, and most efficient way to get the right "4D" texture coordinates for drawing stretched quads?
Implementations are allowed to decompose quads into two triangles and if you visualize this as two triangles you can immediately see why it interpolates texture coordinates the way it does. That texture mapping is correct ... for two independent triangles.
That diagonal seam coincides with the edge of two independently interpolated triangles.
Projective texturing can help as you already know, but ultimately the real problem here is simply interpolation across two triangles instead of a single quad. You will find that while modifying the Q coordinate may help with mapping a texture onto your quadrilateral, interpolating other attributes such as colors will still have serious issues.
If you have access to fragment shaders and instanced vertex arrays (probably rules out OpenGL ES), there is a full implementation of quadrilateral vertex attribute interpolation here. (You can modify the shader to work without "instanced arrays", but it will require either 4x as much data in your vertex array or a geometry shader).
Incidentally, texture coordinates in OpenGL are always "4D". It just happens that if you use something like glTexCoord2f (s, t) that r is assigned 0.0 and q is assigned 1.0. That behavior applies to all vertex attributes; vertex attributes are all 4D whether you explicitly define all 4 of the coordinates or not.
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.