View the inside of a cylinder - opengl

If I draw a gluCylinder with a gluDisk on top. Without culling enabled, I get the desired cylinder with lid effect. However, if I enable culling, the disk (aka lid) disappears. Why is that? This is the main question. In addition, with culling enabled the back faces of the cylinder are also not drawn. I get why this is happening but I would still like to see the inside of the cylinder drawn. The code is:
glPushMatrix()
quadratic = gluNewQuadric()
gluQuadricNormals(quadratic, GLU_SMOOTH)
gluQuadricTexture(quadratic, GL_TRUE)
glRotatef(90, 1, 0, 0)
glTranslate(0, 0, -3*sz)
gluCylinder(quadratic, 0.75*sz, 0.75*sz, 3.0*sz, 32, 32)
gluDisk(quadratic, 0.0, 0.75*sz, 32, 32)
glPopMatrix()

Your disk is facing in the wrong direction (wrong winding). Therefore, it is culled. You can try to reverse its orientation using gluQuadricOrientation, this should do the trick. For more information, refer to the OpenGL spec for gluDisk and glCullFace.

A disk is just a plane without any thickness. So one side is front and the other is back and with culling enabled one of those gets culled away. You are probably just seeing the culled away side. If this is not the side you want to see, just rotate the disk around. Nothing fancier to it. So just wrap it into a:
glPushMatrix();
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gluDisk(quadratic, 0.0, 0.75*sz, 32, 32);
glPopMatrix();
Or, like kroneml suggests, change its triangles' orientations. Decide for yourself which one is more conceptually correct in your situation.

Related

OpenGL Near Clip Plane

I'm working on interactive scenes for a computer graphics course. I've set up a program which will generate color cubes, and let me rotate them with the keyboard. However they're getting cut open by the near clip plane of my camera:
I've tried to use gluPerspective, but the OpenGL documentation doesn't give any examples of its use. I found it being used in an example program online, and semi-replicated their code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 65, 1, 0.01, 100 );
glMatrixMode(GL_MODELVIEW);
Any thoughts?
UPDATE:
As suggested in the comments below, I tried using glFrustum instead, with the following code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -0.5, 0.5, -0.5, 0.5, 0.1, 100 );
glMatrixMode(GL_MODELVIEW);
Again, there was no difference. Am I not pushing the resulting matrices correctly or something?
Perhaps you need to move your objects a little farther from the Camera. Right now it seems that they are closer than 0.0.
Considering your update "I moved the cubes one whole unit away from the camera, and now as they rotate they get clipped by both the near and the far clip planes" your cubes may be too large for your clipping depth (100 - 0.1). Move cubes away from the camera by 50 and set your clipping planes to 0.1 .. 1000 to make sure everything fits.
If the problem remains we might need to look at your matrices code.

Stop light from getting vertices transformations

I'm trying to build a scene where there's a perspective looking at a textured cube and a light.
What's supposed to happen is that the light should stay somewhere above the cube, while the cube rotates (against its center) below that light.
What actually happends is that the light also rotates when the cube rotates.
I've tried googling this and looking similar SO questions but I found nothing that helped. Following OpenGL docs I'm understanding that the light position is affected by modelview matrix transformations, but I also understood that pushing/popping the matrix before/after said transformations would make it so that the light is no longer affected by them. However I can't make it work, the light keeps on rotating no matter if I isolate the modelview transformations (for the cube) to push/pop or if I load the identity matrix afterwards.
Here's the code (it's in Java using JOGL):
//this array goes into lightPositionBuffer
private float[] lightPosition = {0, 0, 0, 1.0f};
public void display(GLAutoDrawable gLDrawable) {
//code for clearing screen, binding the textures, etc.
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL2.GL_CCW);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, cubeVerticesBuffer);
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, cubeTextureCoordsBuffer);
//rotate the cube
gl.glPushMatrix();
gl.glTranslatef(cubeCenterXInitial,cubeCenterYInitial,cubeCenterZInitial);
gl.glRotatef(rotationAmountY, 1, 0, 0);
gl.glTranslatef(-cubeCenterXInitial,-cubeCenterYInitial,-cubeCenterZInitial);
rotationAmountY+=1.5f;
gl.glDrawElements(GL.GL_TRIANGLE_STRIP, cubeIndexes.length, GL.GL_UNSIGNED_BYTE, cubeIndexesBuffer);
gl.glPopMatrix();
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
//Position The Light:
gl.glPushMatrix();
//lightPositionBuffer is a FloatBuffer containing the lightPosition float array declared above:
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPositionBuffer);
gl.glPopMatrix();
//Enable Light 0
gl.glEnable(GL2.GL_LIGHT0);
gl.glEnable(GL2.GL_LIGHTING);
}
Here's what's happening:
Ok I've fixed it. Here's the two important points:
As luke was mentioning in his answer, there's nothing wrong with my code as far as transformations are concerned. As it is, the transofrmations only affect the mesh, the light stays in fact still.
The reason why it looks like my cube has a light rotating around it (when in fact the light is still) is, in one word, NORMALS.
In more words: it's the lack of normals declaration for my cube's faces. Yep, who knew, I didn't. When you have some faces (like triangles and quads) and a light, not declaring normals will NOT simply have your surfaces not being impacted by the light. They are in fact impacted, but it's all weird (as you can see from my screenshots in the question text).
So basically what I did to fix it is look at Nehe's (I love those guys) lesson 07 :
http://nehe.gamedev.net/tutorial/texture_filters_lighting__keyboard_control/15002/
At the bottom of the page there you have the code for a ton of languages and libraries, I personally used the JOGL version but any one will do fine.
Then I also looked at the OpenGL docs just to see how I can declare my vertices/indices/normals as arrays (rather then individually):
http://www.songho.ca/opengl/gl_vertexarray.html
Try adding a glLoadIdentity() right before your second glPushMatrix() call:
gl.glPushMatrix();
gl.glLoadIdentity(); // This
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightPositionBuffer);
gl.glPopMatrix();
As it stands in your original post, that push/pop pair aren't doing anything. There aren't any matrix operations between them. glPushMatrix() does not reset the active matrix, it only preserves the current set of values so you can return to that state.
I don't think your error is in the code you've posted. Can you provide a minimal working example that still exhibits your problem?

OpenGL cube not rendering properly

I have a problem when rendering cubes in OpenGL.I am drawing two cubes, one is a wire cube and is centered around the origin, while the other is offset from the origin and is solid. I have mapped some keys to rotate the objects by some degrees wrt to the origin, so the whole scene can rotate around the origin.
The problem is, when I render the scene, when the wire cube is supposed to be infront of the other solid cube, it does not display itself correctly.
In the image above, the colored cube is supposed to be behind the wire cube. i.e. the green wire cube should be on top.
Also the cube is not behaving properly.
After I rotate it a little bit around the x axis (current horizontal line).
The cube has missing faces and is not rendering correctly.
What am I doing wrong?
I have coded the following
Note that rotateX,rotateY,rotateZ are mapped to keys, and are my global rotation variables.
//The Initialize function, called once:
void Init(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Depth Buffer Setup // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHTING);
}
void draw(){
//The main draw function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45, 640/480.0, .5, 100);
glMatrixMode(GL_MODELVIEW); //select the modelview matrix.
glLoadIdentity ();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
glRotatef(rotateX,1,0,0);
glRotatef(rotateY,0,1,0);
glRotatef(rotateZ,0,0,1);
drawScene(); // this just draws the main axis lines,
glutWireCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-2,1,0);
drawNiceCube();
glPopMatrix();
glutSwapBuffers();
}
The code for the drawNiceCube() is just using GL_QUADS, while the drawWireCube is built in in GLUT.
EDIT:
I have posted the full code at http://pastebin.com/p1kwPjEM, sorry if it is not well documented.
Did you also request a window with a depth buffer?
glutInitDisplayMode( ... | GLUT_DEPTH | ...);
Update:
Did you somewhere enable face culling?
glEnable(GL_CULL_FACE);
This is may be cause of clockwise
10.090 How does face culling work? Why doesn't it use the surface normal?
OpenGL face culling calculates the signed area of the filled primitive in window coordinate space. The signed area is positive when the window coordinates are in a counter-clockwise order and negative when clockwise. An app can use glFrontFace() to specify the ordering, counter-clockwise or clockwise, to be interpreted as a front-facing or back-facing primitive. An application can specify culling either front or back faces by calling glCullFace(). Finally, face culling must be enabled with a call to glEnable(GL_CULL_FACE); .
OpenGL uses your primitive's window space projection to determine face culling for two reasons. To create interesting lighting effects, it's often desirable to specify normals that aren't orthogonal to the surface being approximated. If these normals were used for face culling, it might cause some primitives to be culled erroneously. Also, a dot-product culling scheme could require a matrix inversion, which isn't always possible (i.e., in the case where the matrix is singular), whereas the signed area in DC space is always defined.
However, some OpenGL implementations support the GL_EXT_ cull_vertex extension. If this extension is present, an application may specify a homogeneous eye position in object space. Vertices are flagged as culled, based on the dot product of the current normal with a vector from the vertex to the eye. If all vertices of a primitive are culled, the primitive isn't rendered. In many circumstances, using this extension
from here
Also you can read here
datenwolf solved my problem. I quote him:
"#JonathanSimbahan: Parts of your code are redundant, but something is missing: You forgot to call Init(); after creating your GLUT window, hence depth testing and all the other state never get enabled. I for one suggest you don't use Init at all and move it's code into the drawing code, where it actually belongs."

OpenGL translating up when it shouldn't

I have a skybox and some water with a waving effect. The skybox and water move as the camera moves. This is all well and good, but when I press space, I want the camera to move up, but without the skybox or water moving up too. The skybox doesn't move, but the water comes up as well as the camera, which I dont want. Anyone know why?
//Camera
glRotatef(elevation, 1,0,0);
glRotatef(heading, 0,1,0);
glRotatef(rot, 0,0,1);
glTranslatef(-eyeX,-eyeY,-eyeZ);
//Skybox
glPushMatrix();
glTranslatef(eyeX,0,eyeZ);
drawCube();
drawSea();
glPopMatrix();
None of the translate variables are being used in drawSea().
Well, for a skybox you should not try to "compensate" the camera. It's far easier to reset the modelview matrix to identity and then just apply only the camera rotation. As it happens this is done by simply taking the modelview matrix and clearing the last column and last row to [0,0,0,1].

Why is my glutWireCube not placed in origin?

I have the following OpenGL code in the display function:
glLoadIdentity();
gluLookAt(eyex, eyey, eyez, atx, aty, atz, upx, upy, upz);
// called as: gluLookAt(20, 5, 5, -20, 5, 5, 0, 1, 0);
axis();
glutWireCube (1.);
glFlush ();
axis() draws lines from (0,0,0) to (10,0,0), (0,10,0) and (0,10,0), plus a line from (1,0,0) to (1,3,0).
My reshape function contains the following:
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45.0, (GLsizei) w / (GLsizei) h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
This image shows the result of running the program with 1. as the argument to glutWireCube:
As you can see, the cube isn't centered around (0,0,0) as the documentation says it should be:
The cube is centered at the modeling
coordinates origin (...) (source)
If I run the program with 5. as the argument, the cube is displaced even further:
Why is that, and how do I place the cubes around (0,0,0)?
FURTHER INFORMATION
It doesn't matter if I switch the order of axis() and glutWireCube. Surrounding axis() with glPushMatrix() and glPopMatrix() doesn't fix it either.
SOLUTION
I modified gluPerspective to start looking further away from the camera, and now the Z-buffering works properly, so it is clear that the cubes are placed around the origin.
Are you sure axis does not mess with the view matrix ?
What happens if you call it after the drawing of the cube ?
Edit to add:
Actually... Looking at the picture closer, it looks like it might be centered at the origin.
The center of the cube seems to align exactly with the intersection of the 3 axes. The only thing that looks suspicious is that the red line does not write over the white edge. do you have Z-buffering properly set up ?
It might be right, I think it's hard to determine due to the perspective ... But I guess it isn't from staring a bit more at it.
To quickly rule out that axis() isn't modifying the model view matrix, surround the call with matrix push/pops:
glPushMatrix();
axis();
glPopMatrix();
Things to investigate/check:
Is this the entire window? It seems odd that the view is down in one corner.
Does it help if you add an increasing rotation before the rendering? That can make it easier to determine the perspective, by giving more clues.
You can also try moving the "camera" around, by changing the arguments to gluLookAt() dynamically.