C - Depth effect in OpenGL - c

I read this tutorial online: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/. More precisely the chapter about projection matrices.
I am trying to apply what I read, to a specific part of what I drew. However I don't see anything different. Did I misunderstand anything or do I just apply it incorrectly?
I am actually drawing 2 houses. And I would like to create this effect: http://www.opengl-tutorial.org/assets/images/tuto-3-matrix/homogeneous.png
My code:
void rescale()
{
glViewport(0,0,500,500);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glOrtho(-6.500, 6.500, -6.500, 6.500, -6.00, 12.00);
}
void setup()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
}
void draw()
{
glPushMatrix();
//draw something in the orthogonal projection
glPopMatrix();
glPushMatrix();
gluPerspective(0.0, 1, -12, 30); //perspective projection
glPushMatrix();
glScalef(0.2,0.2,0.2);
glTranslatef(-1, 0.5, -5);
glColor3f(1.0, 0.0, 0.0);
drawVertexCube();
glPopMatrix();
glPushMatrix();
glScalef(0.2,0.2,0.2);
glTranslatef(-1, 0.5, -40);
glColor3f(0, 1.0, 0.0);
drawVertexCube();
glPopMatrix();
glPopMatrix();
glFlush();
}
This is the result:
As you can see there is no (visible) result. I would like to accentuate the effect much more.

Your gluPerspective call is invalid:
gluPerspective(0.0, 1, -12, 30);
The near and far parameters must both be positive, otherwise the command will generate just an GL error and will leave the current matrix unmodified, so your ortho projection is still in use. Your glPushMatrix()/glPopMatrix() calls won't help because you never enclosed the glOrtho() call in such a block, so you never restore to a state where that matrix is not already applied. Furthermore. the glMatrixMode() inbetween a glLoadIdentity() and the glOrtho seems also quite weird.
You should also be aware that all GL matrix functions besides the glLoad* ones will multiply the current matrix by a new matrix. Since you still have the ortho matrix applied, you would get the product of both matrices, which will totally screw up your results.
Finally, you should be aware that all of the GL matrix strack functionality is deprecated and completely removed in the core profile of modern OpenGL. If you are learning OpenGL nowadays, you should really consider learning the "modern" way in OpenGL (which is basically already a decade old).

Related

Using glMatrixMode() in succession?

How would one go about using two different matrix modes in succession? I.e, say I want to do some operations using glOrtho() to the projection matrix. So I call glMatrixMode(GL_PROJECTION), and then perform the operations. From my understanding, using glPushMatrix() will apply these changes to the projection matrix. Now I want to apply some changes to the modelview matrix. I am confused on how to do this properly. Do I pop the matrix then call glMatrixMode or simply continue with glMatrixMode?
glPushMatrix and glPopMatrix are to store/restore currently selected matrix. Its used for example for sub meshes (like robotic arm) where you need to return to the state of the root submesh ...
What you describe is what glMatrixMode is for. So your code should look like this:
glMatrixMode(GL_PROJECTION);
// here your stuff for setting projection
glMatrixMode(GL_MODELVIEW);
// here your stuff for setting modelview
you should call glMatrixMode before each block of code that is manipulating matrix. Do not expect current matrix is set to stuff you set it to last. That leads to confusion later on ... for example many draw algos change modelview and or texture matrices on the run and in your code you can have something like this:
glMatrixMode(GL_MODELVIEW);
// here your stuff for setting modelview
glMatrixMode(GL_PROJECTION);
// here your stuff for setting projection
object1.draw();
// and here the current matrix could be changed from the object1.draw()
glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
glOrtho(a, b, c,d, e,f);//
glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
//----------
//----------
glMatrixMode(GL_PROJECTION); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
float mat_proj[16];
float mat_model[16];
glGetFloatv(GL_PROJECTION_MATRIX,mat_proj );
glGetFloatv(GL_MODELVIEW_MATRIX ,mat_model);
glMatrixMode(GL_PROJECTION);glLoadIdentity();
glOrtho(a,b,c,d,e,f);
glMatrixMode(GL_MODELVIEW);glLoadIdentity();
//---------
//---------
glMatrixMode(GL_PROJECTION); glLoadMatrixf(mat_proj);
glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mat_model);

Simple primitive rotation Opengl c

Im trying to do a simple rotation in opengl of my primitive object in the projection plane. I want to rotate the object like a propeller but i cant seem to get it going right. When i run the code my object looks like it shrinks into itself (i know its not that, but its rotating funny)
void rotateStuff()
{
spin = spin - .5; // inc for spin
if(spin < 360)
{
spin = spin + 360;
}
glPushMatrix();
glTranslatef(150, 95, 0.0);
glRotatef(spin, 1.0, 0.0, 0.0);
glTranslatef(-150, -95, 0);
displayStuff();
glPopMatrix();
drawButton();
glutSwapBuffers();
}
Heres a snippet of my object
glBegin(GL_POLYGON);
glVertex2i(50, 0);
glVertex2i(50, 75);
glVertex2i(150, 75);
glVertex2i(150, 0);
glEnd(); // end current shape
I think something is wrong with the setting of my origin but what exaclty? am i translating to a wrong origin?
This is a rotation around the x-axis: glRotatef(spin, 1.0, 0.0, 0.0).
Presumably you want things in the x-y plane to stay in the x-y plane,
so you want rotation around the z-axis: glRotatef(spin, 0.0, 0.0, 1.0).

Calling glDrawElements after glInterleavedArrays isn't working

I am writing some openGL wrappers and am trying to run the following code:
void some_func1() {
float vertices[] = {50.0, 50.0, 0.0, 20.0, 50.0, 0.0, 20.0, 60.0, 0.0};
glColor3f(1.0, 0.0, 0.0);
glInterleavedArrays(GL_V3F, 0, vertices);
}
void some_func2() {
int indices[] = {0,1,2};
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
}
void parent_func() {
some_func1();
some_func2();
}
But it would seem that openGL is not picking up the call to glDrawElements in the second function. My routine opens a window, clears it to black, and draws nothing. What's weird is that running this code
void some_func1() {
float vertices[] = {50.0, 50.0, 0.0, 20.0, 50.0, 0.0, 20.0, 60.0, 0.0};
int indices[] = {0,1,2};
glColor3f(1.0, 0.0, 0.0);
glInterleavedArrays(GL_V3F, 0, vertices);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
}
void parent_func() {
some_func1();
}
works exactly as expected: a red triangle is drawn. I've looked through the documentation and searched around, but I can't find any reason that glDrawElements wouldn't work, or would miss data somehow if called in another function. Any ideas?
FYI: I am running this on an Ubuntu 12.04 VM through VirtualBox, 32-bit processor on the host, and freeglut is doing my window handling. I have also set LIBGL_ALWAYS_INDIRECT=1 to work around an issue with the VM's 3D rendering. (not sure if any of that matters but... :))
The reason is, that at the point of drawing with glDrawElements, there is no valid vertex data to draw. When calling glInterleavedArrays (which just does a bunch of gl...Pointer calls under the hood) you are merely telling OpenGL where to find the vertex data, without copying anything. The actual data is not accessed before the drawing operation (glDrawElements). So in some_func1 you are setting a pointer to the local variable vertices, which doesn't exist anymore after the function returns. This doesn't happen in your modified code (where the pointer is set and drawn in the same function).
So either make this array survive until the glDrawElements call or, even better, make OpenGL to actually store the vertex data itself, by employing a vertex buffer object and performing an actual data copy. In this case you might also want to refrain from the awfully deprecated glInterleavedArrays function (which isn't much more than a mere software wrapper around proper gl...Pointer and glEnableClientState calls, anyway).

Trouble Understanding glOrtho

I'm new to openGL and im having trouble understanding the concept of glOrtho. for instance i have:
void display(void)
{
/* clear all pixels */
glClear (GL_COLOR_BUFFER_BIT);
/* draw black polygon (rectangle) with corners at * (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/
glColor3f (0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f (-.25,0,0.0);
glVertex3f (.25, 0, 0.0);
glVertex3f (.25, .25, 0.0);
glVertex3f (-.25, .25, 0.0);
glEnd();
/* don’t wait!
* start processing buffered OpenGL routines */
glFlush (); }
this produces a rectangle and then this "morphs" the rectangle:
void init (void)
/* this function sets the initial state */ {
/* select clearing (background) color to white */
glClearColor (1.0, 1.0, 1.0, 0.0);
/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 1, 0.0, -1.0,1.0);
}
and this pretty much makes it a square and puts in up in the top left corner. I'm not sure how it does that. Are the points transformed in the rectangle?
EDIT:
figured it out. this was very helpful. http://elvenware.sourceforge.net/OpenGLNotes.html#Ortho
glOrtho is used to define an orthographic projection volume:
The signature is glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
left and right specify the x-coordinate clipping planes, bottom and top specify the y-coordinate clipping planes, and near and far specify the distance to the z-coordinate clipping planes. Together these coordinates provide a box shaped viewing volume.
The way you have defined your volume of projection is not centered around the point 3d (0, 0, 0) but (.5, -5, 0) you should have defined your glOrtho this way instead: glOrtho(-.5, .5, -.5, .5, -1.0, 1.0); since you polygon is center around the point 3d (0, 0, 0). (You can also change the coordinates of your polygon to match the center of your projection volume).
Your glOrtho call sets up the viewport such that the top-left is (0,0) and the bottom-right is (1,1), with a valid Z-range of (-1,1).
Now, you drew a square with a top-left of (-0.25,-0.25) to (0.25,0.25).
The glVertex calls do not match the comment just above them. Either change the vertices to the values you stated, or change the glOrtho call:
glOrtho(-0.5, 0.5, 0.5, -0.5, -1.0, 1.0 );

OpenGL Drawing "axis"

For a piece of coursework we have to build a working model of the solar system. I have mine implemented with planets (spheres), but we also have to draw the axis of the planet as a line above and below.
I am finding that using GL_LINES doesn't seem to be working, presumably because of the scale of this project (the radius of the planets is 139000000+).
Simplified example:
void drawAxis(int n)
{
/* Draws the axis for body "n" */
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);
glVertex3f(0, bodies[n].radius, 0);
glVertex3f(0, bodies[n].radius*2, 0);
glEnd();
glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex3f(0, -bodies[n].radius, 0);
glVertex3f(0, -bodies[n].radius*2, 0);
glEnd();
}
void drawBody(int n)
{
if(n==0) {
/* Draws body "n" */
//glRotatef(bodies[n].axis_tilt, 1.0, 0.0, 0.0);
//Scale and position
glTranslatef(0.0, 0.0, 0.0);
glScalef(SCALE,SCALE,SCALE); //why already scaled?
//Axis
drawAxis(n);
//r g b - colour (red, green, blue)
glColor3f(bodies[n].r,bodies[n].g,bodies[n].b);
//radius - size of body (km)
glutSolidSphere (bodies[n].radius/SCALE, 50, 50);
}
}
Draws:
Am I missing something critical here?
What is the best "work around" for drawing axis on this sphere?
glScalef(SCALE,SCALE,SCALE); //why already scaled?
...
glutSolidSphere (bodies[n].radius/SCALE, 50, 50);
This makes no sense. Why would you apply a uniform scale, only to then divide your sphere's scale by it, thus undoing the scale? Wouldn't it make more sense to have no scale at all and just use bodies[n].radius?
This is the source of your problem. See, you undo your unnecessary scale when you draw your sphere, but you don't undo it when you draw your axes. If you take out the unnecessary scale, there's a better chance that it will work.

Resources