OpenGL: Quads seemingly not culled properly - c++

I have built a simple scene like the following:
The problem is, the blue shape is lower than the red one but somehow bleeds through. It looks proper when I rotate it like the following:
From what I searched this could be related to the order of vertices being sent, and here is my definition for those:
Shape* Obj1 = new Quad(Vec3(-5.0, 5.0, 0.0), Vec3(5.0, 5.0, 0.0), Vec3(5.0, 5.0, -10.0), Vec3(-5.0, 5.0, -10.0));
Shape* Obj2 = new Quad(Vec3(-5.0, 3.0, 0.0), Vec3(5.0, 3.0, 0.0), Vec3(5.0, 3.0, -10.0), Vec3(-5.0, 3.0, -10.0));
The Vec3 class just holds 3 doubles for x,y,z coordinates. I add these Vec3 classes to a vector, and iterate through them when I want to draw, as such:
glBegin(GL_QUADS);
for (auto it = vertex_list.begin(); it != vertex_list.end(); ++it)
glVertex3d(it->get_x(), it->get_y(), it->get_z());
glEnd();
Finally, my settings:
glEnable(GL_ALPHA_TEST | GL_DEPTH_TEST | GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glAlphaFunc(GL_GREATER, 0.0f);
glViewport(0, 0, WINDOW_X, WINDOW_Y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0f, 300.0);
// camera origin xyz, point to look at xyz, camera rot xyz
gluLookAt(10, 10, -20, 2.5, 2.5, -10, 0, 1, 0);

You should enable depth test, face culling and alpha testing separately.
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
They are not flags. You cannot use them in that way.

See glEnable:
glEnable — enable or disable server-side GL capabilities
void glEnable(GLenum cap);
cap Specifies a symbolic constant indicating a GL capability.
This means the paramter of glEnable is a constant and not a set of bits and GL_ALPHA_TEST, GL_DEPTH_TEST, GL_CULL_FACE are symbolic constats and not bits of a bit set.
Change your code like this:
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
See OpenGL Specifiction - 17.3.4 Depth Buffer Test, p. 500:
17.3.4 Depth Buffer Test
The depth buffer test discards the incoming fragment if a depth comparison fails. The comparison is enabled or disabled with the generic Enable and Disable commands using target DEPTH_TEST.
See OpenGL Specifiction - 14.6.1 Basic Polygon Rasterization, p. 473:
Culling is enabled or disabled by calling Enable or Disable with target CULL_FACE.

Related

OpenGL object not rotating

So, I've been trying to rotate a single object in an OpenGL/GLUT environment.
After going through several questions on SO and the like, I've written what appears to be correct code, but no dice. Does anyone know how to make this work?
PS: I've tried changing the GLMatrixmode to Projection, but that just shows a black screen. Same thing happens if I use glLoadIdentity().
Here's my rendering code
void display()
{
preProcessEvents();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(Camera::position.x, Camera::position.y, Camera::position.z,
Camera::position.x+Math::sind(Camera::rotationAngles.x)*Math::cosd(Camera::rotationAngles.y),
Camera::position.y+Math::cosd(Camera::rotationAngles.x),
Camera::position.z+Math::sind(Camera::rotationAngles.x)*Math::sind(Camera::rotationAngles.y),
0.0, 1.0, 0.0);
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0);
glVertex3f(-1, 0,-3);
glColor3f(0, 1, 0);
glVertex3f(0.0f, 2.0f,-3);
glColor3f(0, 0, 1);
glVertex3f(1.0f, 0.0f,-3);
glEnd();
glBindTexture(GL_TEXTURE_2D, tex->textureID);
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
glTexCoord2f(100, 100);
glVertex3f(100,0,100);
glTexCoord2f(-100, 100);
glVertex3f(-100,0,100);
glTexCoord2f(-100,-100);
glVertex3f(-100,0,-100);
glTexCoord2f(100,-100);
glVertex3f(100,0,-100);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
object1.draw();
glTranslatef(-10.0, 10.0, 0.0);
glBindTexture(GL_TEXTURE_2D, tex2->textureID);
gluQuadricTexture(quad,1);
gluSphere(quad,10,20,20);
glBindTexture(GL_TEXTURE_2D, 0);
//RELEVANT CODE STARTS HERE
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glRotatef(190, 0.0, 0.0, 1.0);
glPopMatrix();
glutSwapBuffers();
}
Are you aware what glPushMatrix and glPopMatrix do? They save and restore the "current" matrix.
By enclosing your rotation in that and then doing no actual drawing operation before restoring the matrix the entire sequence of code beginning with //RELEVANT CODE STARTS HERE is completely pointless.
Even if you did not push/pop, your rotation would only be applied the next time you draw something. Logically you might think that would mean the next time you call display (...), but one of the first things you do in display (...) is replace the current matrix with an identity matrix (line 3).
In all honesty, you should consider abandoning whatever resource you are currently using to learn OpenGL. You are using deprecated functionality and missing a few fundamentals. A good OpenGL 3.0 tutorial will usually touch on the basics of transformation matrices.
As for why changing the matrix mode to projection produces a black screen, that is because the next time you call display (...), gluLookAt operates on the projection matrix. In effect, you wind up applying the camera transformation twice. You should really add glMatrixMode (GL_MODELVIEW) to the beginning of display (...) to avoid this.
You do the rotation (and reset it with glPopMatrix) after you draw, do the rotation code before the glBegin/glEnd calls.
Or just move to the shader based pipeline and manage you own transformation matrices.

Inconsistency of shading in polygons on the same axis in OpenGL

I am building a house in OpenGL. On the outside and on the inside where there are doors or windows, I use a Quad to go below and above the windows all the way around the house, and then a quad to fill in the gaps between windows. These will have the same plane value, but for some reason GL_LIGHT passes shadows onto some. Any clue why?
Quad between windows
glBegin(GL_QUADS);
glTexCoord2d(0, 0);glVertex3d(0, 1.1, 0);
glTexCoord2d(2, 0);glVertex3d(0, 1.1, 2);
glTexCoord2d(2, 1.6);glVertex3d(0, 2.7, 2);
glTexCoord2d(0, 1.6);glVertex3d(0, 2.7, 0);
glEnd();
Below windows
glBegin(GL_QUADS);
glTexCoord2d(0, 0);glVertex3d(0, 0.1, 0);
glTexCoord2d(15, 0);glVertex3d(0, 0.1, 15);
glTexCoord2d(15, 1);glVertex3d(0, 1.1, 15);
glTexCoord2d(0.0, 1);glVertex3d(0, 1.1, 0);
glEnd();
Above windows
glBegin(GL_QUADS);
glTexCoord2d(0, 2.6);glVertex3d(0, 2.7, 0);
glTexCoord2d(15, 2.6);glVertex3d(0, 2.7, 15);
glTexCoord2d(15, 3.0);glVertex3d(0, 3.1, 15);
glTexCoord2d(0.0,3.0);glVertex3d(0, 3.1, 0);
glEnd();
here is the code for the light
GLfloat light_position[] = { 50, 50, -1.0};
GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat ambient[] = { 1.0, 1.0, 1.0, 1.0 };
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_NORMALIZE);
glLightfv(GL_LIGHT0, GL_POSITION , light_position );
glLightfv(GL_LIGHT0, GL_SPECULAR , specular);
glLightfv(GL_LIGHT0, GL_DIFFUSE , diffuse );
glLightfv(GL_LIGHT0, GL_AMBIENT , ambient );
Here is a screenshot of the result
http://imgur.com/WsgZWBF
Why is it doing this, and is there any way to fix it?
You need to supply (meaningful) vertex/face normals for OpenGL's lighting to work properly:
18.020 Why are my objects all one flat color and not shaded and illuminated?
This effect occurs when you fail to supply a normal at each vertex.
OpenGL needs normals to calculate lighting equations, and it won't calculate normals for you (with the exception of evaluators). If your application doesn't call glNormal*(), then it uses the default normal of (0.0, 0.0, 1.0) at every vertex. OpenGL will then compute the same, or nearly the same, lighting result at each vertex. This will cause your model to look flat and lack shading.
The solution is to simply calculate the normals that need to be specified at any given vertex. Then send them to OpenGL with a call to glNormal3f() just prior to specifying the vertex, which the normal is associated with.

OpenGL depth buffer isn't working

I am attempting to make a simple drawing using openGL. However, the depth buffer doesn't appear to be working.
Other people with a similar problem are typically doing one of two things wrong:
Not including glEnable(GL_DEPTH_TEST)
Bad clipping values
However, my code does not have either of these problems.
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluPerspective(25.0,1.0,10.0,200.0);
// Set the camera location
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(20.0, 10.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Cull backfacing polygons
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE)
drawCoordinateAxis();
drawBox(5.0,2.0,5.0,0.8,0.0,0.0);
glTranslated(1.0,-1.0,1.0); //The box is 5x2x5, it is shifted 1 unit down and 1 in the x and z directions
drawBox(5.0,2.0,5.0,0.0,1.0,1.0);
...
When I execute my code, this is drawn. http://imgur.com/G9y41O1
Note that the blue box and the red box collide, so the red box should be covering part of the blue box.
The functions drawCoordinateAxis() and drawBox() just draw a few primitives, nothing fancy inside.
I am running this on Debian squeeze.
void reshape(GLint width, GLint height)
{
g_Width = width;
g_Height = height;
glViewport(0, 0, g_Width, g_Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
glMatrixMode(GL_MODELVIEW);
}
So set Matrix Mode to GL_PROJECTION first, then gluPerspective.... and then back to MODELVIEW mode.

Order of execution of depth_clamp and depth_test

does depth clamp occurs before depth test or after depth test?
I am rendering a primitive with coordinates > 1.0 and <-1.0 and using depth clamping with depth test. But when i enable depth test it does not render any geometry.
Here is my code:
GLfloat vertices[]=
{
0.5f,0.5f,0.5f,
-0.5f,0.5f,0.5f,
-0.5f,-0.5f,0.5f,
0.5f,-0.5f,0.5f,
0.5f,-0.5f,-0.5f,
-0.5f,-0.5f,-0.5f,
-0.5f,0.5f,-0.5f,
0.5f,0.5f,-0.5f
}
for(int i=0;i<24;i++)
vertices[3*i+2]*=25;
glEnable(GL_DEPTH_CLAMP);
// when i comment stmt below, it draws triangle strips
glEnable(GL_DEPTH_TEST);
glClearDepth(15.0f);
glClearColor (1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLE_STRIP,0,6);
How to use depth test and clamping together?
why does the above code does not draw anything on the screen with depth test enabled?
From OpenGL 4.3, 17.3.6:
If depth clamping (see section 13.5) is enabled, before the incoming fragment’s zw is compared, zw is clamped to the range [min(n; f ); max(n; f )]
i am assuming that by default it is GL_LEQUAL.
That's why you should post fully working examples when you don't know what's going on. The default depth test is GL_LESS. 1.0 is not less than 1.0, so all of your 0.5 depth vertices fail the depth test.
Also, your loop:
vertices[3*i+2]*=25
This is overwriting memory. Your index is going far off the end of the array, since it only has 24 elements. You probably meant to loop 8.

How to draw a filled envelop like a cone on OpenGL (using GLUT)?

I am using freeglut for opengl rendering...
I need to draw an envelop looking like a cone (2D) that has to be filled with some color and some transparency applied.
Is the freeglut toolkit equipped with such an inbuilt functionality to draw filled geometries(or some trick)?
or is there some other api that has an inbuilt support for filled up geometries..
Edit1:
just to clarify the 2D cone thing... the envelop is the graphical interpretation of the coverage area of an aircraft during interception(of an enemy aircraft)...that resembles a sector of a circle..i should have mentioned sector instead..
and glutSolidCone doesnot help me as i want to draw a filled sector of a circle...which i have already done...what remains to do is to fill it with some color...
how to fill geometries with color in opengl?
Edit2:
All the answers posted to this questions can work for my problem in a way..
But i would definitely would want to know a way how to fill a geometry with some color.
Say if i want to draw an envelop which is a parabola...in that case there would be no default glut function to actually draw a filled parabola(or is there any?)..
So to generalise this question...how to draw a custom geometry in some solid color?
Edit3:
The answer that mstrobl posted works for GL_TRIANGLES but for such a code:
glBegin(GL_LINE_STRIP);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(200.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(200.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
which draws a square...only a wired square is drawn...i need to fill it with blue color.
anyway to do it?
if i put some drawing commands for a closed curve..like a pie..and i need to fill it with a color is there a way to make it possible...
i dont know how its possible for GL_TRIANGLES... but how to do it for any closed curve?
On Edit3: The way I understand your question is that you want to have OpenGL draw borders and anything between them should be filled with colors.
The idea you had was right, but a line strip is just that - a strip of lines, and it does not have any area.
You can, however, have the lines connect to each other to define a polygon. That will fill out the area of the polygon on a per-vertex basis. Adapting your code:
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(200.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(200.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 200.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 0.0);
glEnd();
Please note however, that drawing a polygon this way has two limitations:
The polygon must be convex.
This is a slow operation.
But I assume you just want to get the job done, and this will do it. For the future you might consider just triangulating your polygon.
I'm not sure what you mean by "an envelop", but a cone is a primitive that glut has:
glutSolidCone(radius, height, number_of_slices, number_of_stacks)
The easiest way to fill it with color is to draw it with color. Since you want to make it somewhat transparent, you need an alpha value too:
glColor4f(float red, float green, float blue, float alpha)
// rgb and alpha run from 0.0f to 1.0f; in the example here alpha of 1.0 will
// mean no transparency, 0.0 total transparency. Call before drawing.
To render translucently, blending has to be enabled. And you must set the blending function to use. What you want to do will probably be achieved with the following. If you want to learn more, drop me a comment and I will look for some good pointers. But here goes your setup:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Call that before doing any drawing operations, possibly at program initialization. :)
Since you reclarified your question to ask for a pie: there's an easy way to draw that too using opengl primitives:
You'd draw a solid sphere using gluSolidSphere(). However, since you only want to draw part of it, you just clip the unwanted parts away:
void glClipPlane(GLenum plane, const GLdouble * equation);
With plane being GL_CLIPPLANE0 to GL_CLIPPLANEn and equation being a plane equation in normal form (ax + by + c*z + d = 0 would mean equation would hold the values { a, b, c, d }. Please note that those are doubles and not floats.
I remember there was a subroutine for that. But it's neither too hard to do by yourself.
But I don't understand the 2D -thing. Cone in 2D? Isn't it just a triangle?
Anyway, here's an algorithm to drawing a cone in opengl
First take a circle, subdivision it evenly so that you get a nice amount of edges.
Now pick the center of the circle, make triangles from the edges to the center of the circle. Then select a point over the circle and make triangles from the edges to that point.
The size shape and orientation depends about the values you use to generate the circle and two points. Every step is rather simple and shouldn't cause trouble for you.
First just subdivision a scalar value. Start from [0-2] -range. Take the midpoint ((start+end)/2) and split the range with it. Store the values as pairs. For instance, subdividing once should give you: [(0,1), (1,2)] Do this recursively couple of times, then calculate what those points are on the circle. Simple trigonometry, just remember to multiply the values with π before proceeding. After this you have a certain amount of edges. 2^n where n is the amount of subdivisions. Then you can simply turn them into triangles by giving them one vertex point more. Amount of triangles ends up being therefore: 2^(n+1). (The amounts are useful to know if you are doing it with fixed size arrays.
Edit: What you really want is a pie. (Sorry the pun)
It's equally simple to render. You can again use just triangles. Just select scalar range [-0.25 - 0.25], subdivide, project to circle, and generate one set of triangles.
The scalar - circle projection is simple as: x=cos(v*pi)r, y=sin(vpi)*r where (x,y) is the resulting vertex point, r is a radius, and trigonometric functions work on radiances, not degrees. (if they work with degrees, replace pi with 180)
Use vertex buffers or lists to render it yourself.
Edit: About the coloring question. glColor4f, if you want some parts of the geometry to be different by its color, you can assign a color for each vertex in vertex buffer itself. I don't right now know all the API calls to do it, but API reference in opengl is quite understandable.
On the edit on colors:
OpenGL is actually a state machine. This means that the current material and/or color position is used when drawing. Since you probably won't be using materials, ignore that for now. You want colors.
glColor3f(float r, float g, float b) // draw with r/g/b color and alpha of 1
glColor4f(float r, float g, float b, float alpha)
This will affect the colors of any vertices you draw, of any geometry you render - be it glu's or your own - after the glColorXX call has been executed. If you draw a face with vertices and change the color inbetween the glVertex3f/glVertex2f calls, the colors are interpolated.
Try this:
glBegin(GL_TRIANGLES);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-3.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 3.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(3.0, 0.0, 0.0);
glEnd();
But I pointed at glColor4f already, so I assume you want to set the colors on a per-vertex basis. And you want to render using display lists.
Just like you can display lists of vertices, you can also make them have a list of colors: all you need to do is enable the color lists and tell opengl where the list resides. Of course, they need to have the same outfit as the vertex list (same order).
If you had
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices_);
glDisableClientState(GL_VERTEX_ARRAY);
you should add colors this way. They need not be float; in fact, you tell it what format it should be. For a color list with 1 byte per channel and 4 channels (R, G, B and A) use this:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices_);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors_);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
EDIT: Forgot to add that you then have to tell OpenGL which elements to draw by calling glDrawElements.