Half cylinder/Closed cylinder in opengl - c

I currently have a cylinder
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0, 0, 0);
gluDisk(quad, 0.0, cylinder->radius, 300, 90);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();
but it only renders half of a cylinder instead of the whole thing (the half coming towards the view). Second issue is I don't know how to close the cylinder. The gludisk only closes the bottom of the cylinder and I'm not sure how to close the top side.

If I understand what you're describing, it sounds like you might have back face culling enabled. Do you have a glEnable(GL_CULL_FACE) call in your code? This will eliminate all polygons that face away from you. In any case, once you draw a cylinder that is closed at both sides, it will be fine to keep it enabled.
You can close the cylinder at the top with another gluDisk() call, after applying a translation that moves it to (0, 0, height). For correctness, I believe you need to rotate the disk that closes the cylinder at the bottom. Otherwise it will face to the inside of the cylinder instead of to the outside, which affects the normals, and would get it eliminated by back face culling when it should be visible.
For the full thing, it should look something like this (untested):
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0f, 0.0f, 0.0f);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
glPushMatrix();
glTranslatef(0.0f, 0.0f, cylinder->height);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
glPopMatrix();
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();

Related

OpenGL Try to draw square but its display a rectangle

I try to draw a simple square by OpenGL but the result its display a rectangle. I guess that the problem is in the reshape function but I have no idea why (I'm new to OpenGL).
I what to keep aspect when I resize the window, that is not to stretch or shrink my image.
image screenshot
my reshape function
#define WINDOW_W 640
#define WINDOW_H 480
void reshape(int width, int height) {
if (height == 0)
height = 1;
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width >= height)
gluOrtho2D(0.0f, (GLdouble)WINDOW_W * aspect, (GLdouble)WINDOW_H, 0.0f);
else
gluOrtho2D(0.0f, (GLdouble)WINDOW_W, (GLdouble)WINDOW_H / aspect, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
my draw function
void display(void) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
// x=50 y=50 w=100 h=100 a square
glBegin(GL_QUADS);
glVertex2i(50, 50);
glVertex2i(50, 150);
glVertex2i(150, 150);
glVertex2i(150, 50);
glEnd();
glutSwapBuffers();
}
Right now, your "square" will always be exactly 1.3333 (640 / 480) times as tall as it is wide, because while you do take the actual window size into account and compute the actual aspect ratio given the actual window size, you multiply that with 640 for the width and 480 for the height, for whatever reason.
And that won't work since that will always stretch your actual aspect ratio by a factor of 1.3333 making your square always 1.3333 as tall as it is wide.
To solve this, just multiply the arguments to the gluOrtho2D() call with the same value, depending on what the extent in your world space or "view space" should be for a square view space with a square aspect ratio.

Use values instead of -1...1 for OpenGL drawing shapes?

If I wanted to draw a plane in OpenGL, I would do something like the below:
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();
This draws a white plane that covers 50% of the canvas (from -0.5 to 0.5 on two axes). I want to use numbers instead, however. I don't want to use -1 to 1, but instead something like 0 to n, where n is the dimension of my canvas. For the above example, something like 250 to 750 on two axes on a 1000 pixel canvas rather than -0.5 to 0.5.
That's what the transformation matrices are for. In your case you'd set a ortho projection matrix with the limits as you desire. In your example case
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1000, 0, 1000, -1, 1);
would set up a viewing volume so that the boundaries are at 0,0 for the lower left corner and 1000,1000 for the upper right.
Note that this (and the code you've given) use the old, deprecated fixed function pipeline. You should drop that in favour of a shader based approach.

OpenGL 2D moving relation

I have the two methods hich are doing the same thing. Now I am wondering what is their differences and which one can perform faster.
Here are the methods:
1th Method
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0); glVertex2f( x, y);
glTexCoord2f( 1, 0); glVertex2f( x+texWidth, y);
glTexCoord2f( 1, 1); glVertex2f( x+texWidth, y+texHeight);
glTexCoord2f( 0, 1); glVertex2f( x, y+texHeight);
glEnd();
x++; y++;
2th Method
glPushMatrix();
glTranslatef(x, y, 0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0); glVertex2f( 0.0f, 0.0f);
glTexCoord2f( 1, 0); glVertex2f( 1.0f, 0.0f);
glTexCoord2f( 1, 1); glVertex2f( 1.0f, 1.0f);
glTexCoord2f( 0, 1); glVertex2f( 0.0f, 1.0f);
glEnd();
glPopMatrix();
x++; y++;
Regarding performance, you are using immediate mode, which is slow anyway (its the "old" way of doing things; unfortunately most OpenGL tutorials on the web are hopelessly outdated). Use buffers (gpu-side) like VBOs and VAOs if you really care about performance.
A nice modern tutorial is http://open.gl/ which introduces VBOs here: http://open.gl/drawing
The second method is alot faster, because it is translating the whole matrix, and doesn't do many calculations as it does in method one.
The second method is a lot faster, because it translates the whole QUAD matrix with less calculations.

Rotate object around another object

I drew two rectangles in my scene, and now I'm trying to rotate one rectangle around the other.
When I press the "Left key" my first rectangle moves in direction to the other, but I don't have the effect of rotate because it is only moving in a straight line in direction of the other rectangle.
How do I change the Z direction of the first rectangle?
tl;dr: It's like a solar system, but I don't understand how can I have the depth effect.
I'm using GLUT and OpenGL.
EDIT: More Info:
This is my current code (function that shows the scene):
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glFlush();
}
And a image to help:
Please enable depth test to hide objects beyond other objects.
Give a high value z vaue for the far object.
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -26.0f); // Z value of behind object is set far from eye
glPopMatrix();
What you want to do is moderately complicated.
The only way I know to locate rectangles in 3-space is to build them using glVertex3f() like this:
glBegin(GL_QUADS);
glVertex3f(x0, y0, z0);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
Your "solar system" will have to be located in screen coordinates: X->left/right, Y->up/down, Z->into/out of screen. To create the effect of orbiting, you'll have to recalculate all four X and Z for each movement increment.
I also suggest using gluLookAt() if you want to see a different view.
The man page for glPerspective() says that zNear is always positive but you've given it a negative number. I'd leave that line commented out until I saw some orbiting.
HTH.

Changing OpenGL vertex attributes in a sample

I am using this tutorial / sample to do some basic object tracking on the iPhone. Everything works fine, I even tweaked the performance a whole lot, but I am still stuck with one problem.
The basic problem is that I do not understand OpenGL well enough and I should be punished for shamefully taking sample code and turning it into something that works for me. As a matter of fact I am being punished;
The sample shows how to render (with shaders) the iPhone's camera into an offscreen texture in order to be able to process it and show it on screen. Now I have figured out that it draws the texture/layer using an array of vertex attributes (a principle I barely understand, despite my Google searches).
The vertex array's are as follows:
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat textureVertices[] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
};
I have also figured out that these vertex attributes can alter the orientation of the drawn texture. The texture is now drawn in portrait, which means that if I keep my iPhone in landscape (which I desire), and let the views rotate along, everything I see on the screen is a camera with a 90 degree angle.
I think I narrowed the problem down enough to blame these vertexes and I have been messing around with their values somewhat but without any acceptable result.
Is there anybody out there who can help me draw the texture in landscape?
P.S: if I inverse the values of 'squareVerticles' I am able to get a 180 degree rotated picture. But I want the texture to be rotated 90 degrees, not 180.
Imagine that your screen has normalized coordinates that go from -1.0,-1.0 (left, bottom) to 1.0, 1.0. The first array specifies the coordinates of the vertices of a square (presumably as a triangle strip, because they are given in a "Z" fashion).
The second array specifies the texture coordinates. Same thing, except that they are in the 0.0, 1.0 range.
So, to rotate 90 degrees clockwise:
1.0f, 0.0f
0.0f, 0.0f
1.0f, 1.0f
0.0f, 1.0f
anticlockwise:
0.0f, 1.0f
1.0f, 1.0f
0.0f, 0.0f
1.0f, 0.0f
I hope that works!

Resources