I drawed a triangle {(0,0), (1,0), (0,1)}. Now i want to draw a second one. But for some reason not any triangle draws. For example triangle: {(1.5654, 1.2), (1.1, 1.4564), (1.5, 1.15)} is drawn normal, but triangle {(1,1), (1,0), (0, 1)} doesn't appear. Hear the code i use to draw:
glBegin(GL_TRIANGLES);
invers_sh.setAttributeValue(b_colorLoc, colors[0]);
glVertex2d(1.5654, 1.2);
invers_sh.setAttributeValue(b_colorLoc, colors[1]);
glVertex2d(1.1, 1.4564);
invers_sh.setAttributeValue(b_colorLoc, colors[2]);
glVertex2d(1.5, 1.15);
glEnd();
For first triangle it's the same code (but coordinates are different). I tryed to unite both drawings (in one glBegin/glEnd) - same result. What i do wrong?
you need to draw all vertices in a clockwise or counter clockwise order depending on frontface setting, you can google it for more details.
As pointed out in the other answer, you need to draw the vertices for all triangles in the same order, clockwise or counter-clockwise (OpenGL default).
To correct the ordering, just swap out the first and last vertex.
You can control this behaviour (called FaceCulling) with OpenGL-commands like glCullFace, glFrontFace and glEnable/glDisable with GL_CULL_FACE.
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 want to draw a 4pointed star using GLUT and openGL in C++. Here is my code
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f,6.0f,0.0f);
glVertex3f(1.0f,4.0f,0.0f);
glVertex3f(3.0f,3.0f,0.0f);
glVertex3f(1.0f,2.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(-1.0f,2.0f,0.0f);
glVertex3f(-3.0f,3.0f,0.0f);
glVertex3f(-1.0f,4.0f,0.0f);
glEnd();
The problem is the shape directly goes to 3,3 from 0,6
can anyone help me how to fix this,
screenshot
I want something like this
desired output
The 1st point of the the GL_TRIANGLE_FAN primitiv is always held fixed (See Triangle primitives). Just start the GL_TRIANGLE_FAN primitiv at one of the "inner" points:
glBegin(GL_TRIANGLE_FAN);
glVertex3f(1.0f,4.0f,0.0f);
glVertex3f(3.0f,3.0f,0.0f);
glVertex3f(1.0f,2.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(-1.0f,2.0f,0.0f);
glVertex3f(-3.0f,3.0f,0.0f);
glVertex3f(-1.0f,4.0f,0.0f);
glVertex3f(0.0f,6.0f,0.0f);
glEnd();
You are creating a triangle fan but setting its central vertex (the initial one) at 0,6,0.
You probably want to change your geometry so that your central vertex is at the origin (for symmetry). It also works to move the first vertex down to the bottom as #Rabbid76 shows.
Say I have two triangles in an opengl 3d setup, with a specific light source. The first triangle:
glEnable(GL_LIGHT0)
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color)
glBegin(GL_TRIANGLES)
glNormal3fv(n1)
glVertex3f(p1)
glVertex3f(p2)
glVertex3f(p3)
glEnd()
Now I draw the second triangle, at a different position
glBegin(GL_TRIANGLES)
glNormal3fv(n2)
glVertex3f(p4)
glVertex3f(p5)
glVertex3f(p6)
glEnd()
but I want the light applied to this triangle AS IF it was located and had the same normal vector as the first triangle. Obviously it is easy to just change the normal vector, but it seems that I can not change the apparent position relative to the light source without also changing the true position of the triangle. Also, since the light properties of my 3d world will not change in time, I would like to precompute this in the beginning and then store it. Any tips?
Why I want to do this: essentially the vision of the player seeing the 3d world will be distorted in some way, such that the position of all 3d objects will change. However this should then not affect the color of the primitives as computed after applying a light source.
I'm using glScalef (-1.0, 1.0, 1.0) to flip my openGL image axis. However this completely messes up the rendering of the objects and the colors. I've tried the following things to no avail:
glEnable(GL_NORMALIZE);
glEnable (GL_DEPTH_TEST) ;
glEnable(GL_COLOR_MATERIAL);
glCullFace(GL_BACK);
If I flip in x and y - glScalef (-1.0, -1.0, 1.0) then the colors are fine, but I don't want to flip both dimensions. Flipping x and z does not fix the colors.
Any ideas?
You changed the handedness of your coordinate space by doing this. Effectively when it comes time to rasterize your triangles, the front becomes the back because the winding direction is reversed.
You should be aware of how the rasterizer determines the front/back face of a polygon. It uses the post-projected position of your vertices and tests the winding direction. You flipped 1-axis in your post-projected coordinate system, which changes handedness (more formally, its chirality). This produces a mirror image and the winding of your vertices is backwards.
You can solve this with glFrontFace (GL_CW), or simply wind your vertices the other way by hand.
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.