Hello guys I am beginner to opengl and trying to understand the concept gluPerspective() funtion. I went through this post gluPerspective parameters- what do they mean? post and I wrote this code
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0,0,500,500);
gluPerspective(45,16/9,1.0,3.0);
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex3f(100.0f,0.0f,2.0f);
glVertex3f(0.0f,0.0f,2.0f);
glVertex3f(0.0f,100.0f,2.0f);
glVertex3f(100.0f,100.0f,2.0f);
glEnd();
glFlush();
This is the dispay function but black screen is rendered.What is wrong in my code
Call glMatrixMode(GL_PROJECTION); before calling gluPerspective.
After that switch back with glMatrixMode(GL_MODELVIEW);.
gluPerspective() sets up a projection matrix under the assumption that your eye point is at the origin, and you're looking down the negative z-axis. The zNear and zFar parameters specify the range of distances along the negative z-axis that will be contained within the view volume.
Therefore, with zNear set to 1.0 and zFar to 3.0, z-values within a range of -1.0 to -3.0 will be within the view volume.
To make your quad visible, you will have to use coordinates within that range. Changing all your z-coordinates from 2.0 to -2.0 would work. The more typical approach is to apply a view transformation to place the geometry where it is needed for the projection transformation.
For example, in your case, you could place the quad around the origin, and then use either gluLookAt(), or a simple translation, to move the geometry down the negative z-axis.
You also need to watch out for the matrix modes. The projection matrix should normally be set in the corresponding matrix mode.
The whole thing will then look like this:
glMatrixMode(GL_PROJECTION);
gluPerspective(45,16/9,1.0,3.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0f, 0.0f, -2.0f);
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex3f(100.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 100.0f, 0.0f);
glVertex3f(100.0f, 100.0f, 0.0f);
glEnd();
Note that the range of your x and y coordinates is far beyond the default coordinate range of [-1.0, 1.0]. You will either want to use additional translation/scaling, or use much smaller values.
Related
For practice I am setting up a 2d/orthographic rendering pipeline in openGL to be used for a simple game, but I am having issues related to the coordinate system.
In short, rotations distort 2d shapes, and I cannot seem to figure why. I am also not entirely sure that my coordinate system is sound.
First I looked for previous answers, but the following (the most relevant 2D opengl rotation causes sprite distortion) indicates that the problem was an incorrect ordering of transformations, but for now I am using just a view matrix and projection matrix, multiplied in the correct order in the vertex shader:
gl_Position = projection * view * model vec4(1.0); //(The model is just the identity matrix.)
To summarize my setup so far:
- I am successfully uploading a quad that should stretch across the whole screen:
GLfloat vertices[] = {
-wf, hf, 0.0f, 0.0, 0.0, 1.0, 1.0, // top left
-wf, -hf, 0.0f, 0.0, 0.0, 1.0, 1.0, // bottom left
wf, -hf, 0.0f, 0.0, 0.0, 1.0, 1.0, // bottom right
wf, hf, 0.0f, 0.0, 0.0, 1.0, 1.0, // top right
};
GLuint indices[] = {
0, 1, 2, // first Triangle
2, 3, 0, // second Triangle
};
wf and hf are 1, and I am trying to use a -1 to 1 coordinate system so I don't need to scale by the resolution in shaders (though I am not sure that this is correct to do.)
My viewport and orthographic matrix:
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
...
glm::mat4 mat_ident(1.0f);
glm::mat4 mat_projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
... though this clearly does not factor in the screen width and height. I have seen others use width and height instead of 1s, but this seems to break the system or display nothing.
I rotate with a static method that modifies a struct containing a glm::quaternion (time / 1000) to get seconds:
main_cam.rotate((GLfloat)curr_time / TIME_UNIT_TO_SECONDS, 0.0f, 0.0f, 1.0f);
// which does: glm::angleAxis(angle, glm::vec3(x, y, z) * orientation)
Lastly, I pass the matrix as a uniform:
glUniformMatrix4fv(MAT_LOC, 1, GL_FALSE, glm::value_ptr(mat_projection * FreeCamera_calc_view_matrix(&main_cam) * mat_ident));
...and multiply in the vertex shader
gl_Position = u_matrix * vec4(a_position, 1.0);
v_position = a_position.xyz;
The full-screen quad rotates on its center (0, 0 as I wanted), but its length and width distort, which means that I didn't set something correctly.
My best guess is that I haven't created the right ortho matrix, but admittedly I have had trouble finding anything else on stack overflow or elsewhere that might help debug. Most answers suggest that the matrix multiplication order is wrong, but that is not the case here.
A secondary question is--should I not set my coordinates to 1/-1 in the context of a 2d game? I did so in order to make writing shaders easier. I am also concerned about character/object movement once I add model matrices.
What might be causing the issue? If I need to multiply the arguments to gl::ortho by width and height, then how do I transform coordinates so v_position (my "in"/"varying" interpolated version of the position attribute) works in -1 to 1 as it should in a shader? What are the implications of choosing a particular coordinates system when it comes to ease of placing entities? The game will use sprites and textures, so I was considering a pixel coordinate system, but that quickly became very challenging to reason about on the shader side. I would much rather have THIS working.
Thank you for your help.
EDIT: Is it possible that my varying/interpolated v_position should be set to the calculated gl_Position value instead of the attribute position?
Try accounting for the aspect ratio of the window you are displaying on in the first two parameters of glm::ortho to reflect the aspect ratio of your display.
GLfloat aspectRatio = SCREEN_WIDTH / SCREEN_HEIGHT;
glm::mat4 mat_projection = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
First off, I'm sorry if I confuse anyone because I don't know how to phrase this, exactly.
Anyway, What I want to do is rotate on 3 axis, but independent of eachother. If I have
glRotatef(getPitch(),1f,0,0);
glRotatef(getYaw(),0,1f,0);
glRotatef(getRoll(),0,0,1f);
Then, it rotates my object on the x axis just fine, but the other two axis rotate on the offset of the x rotation. How do I rotate these all independent of eachother? (On the same object)
Again, Sorry if I confused anyone.
You could push and pop the matrix onto and off the stack, so you could do:
glPushMatrix();
glRotatef( getPitch(), 1.0f, 0.0f ,0.0f );
glPopMatrix();
glPushMatrix();
glRotatef( getYaw(), 0.0f, 1.0f, 0.0f);
glPopMatrix();
glPushMatrix();
glRotatef( getRoll(), 0.0f, 0.0f, 1.0f);
glPopMatrix();
so basically, pushing the matrix, saves the transformation matrix in it's current state. You apply the transformations that you want on the object (in your case rotations around an axis), which updates the matrix. Popping it restores it to the original state before the rotation was applied. You can then apply each rotation independently of the other ones.
I'm trying to zoom out from a polygon with glTranslatef. However, whatever numbers I put in Z (trying to zoom out) inside glTranslatef function, it remains a black window. Here is code:
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix ();
glTranslatef(0, 0, 0.9f); //Here I'm translating
glBegin (GL_POLYGON);
glColor3f(100, 100, 0); glVertex2f(-1.0f, -1.0f);
glColor3f(100, 0, 100); glVertex2f(-1.0f, 1.0f);
glColor3f(25, 25, 25); glVertex2f(1.0f, 1.0f);
glColor3f(100, 50, 90); glVertex2f(1.0f, -1.0f);
glEnd ();
glPopMatrix ();
SwapBuffers (hDC);
Sleep (1);
I tried with following numbers in Z:
0.9 (works)
-0.9 (works)
1.1 (works not)
-1.1 (works not)
Do I need some other code for this or I'm doing it wrong?
If you haven't specified a projection matrix then the standard one will be an orthographic (non-perspective) projection with left-right top-bottom and near-far all being -1,1.
So translating outside that will make the vertices not draw at all.
The reason this does nothing is because you have no transformation matrices setup.
Right now you are drawing in a coordinate space known as Normalized Device Coordinates, which has the viewing volume encompass the range [-1.0, 1.0] in all directions. Any point existing outside that range is clipped.
Vertices specified with glVertex2f (...) are implicitly placed at z=0.0 and translating more than 1.0 unit along the Z-axis will push your vertices outside the viewing volume. This is why -1.1 and 1.1 fail, while 0.9 and -0.9 work fine.
Even if you translate to a position within the viewing volume, without a perspective projection, translating something along the Z-axis is not going to change its size. The only thing that will happen is that eventually the object will be translated far enough that it is clipped and suddenly disappears (which you already experienced with values > 1.0 or < -1.0).
I followed a guide to draw a Lorenz system in 2D.
I want now to extend my project and switch from 2D to 3D. As far as I know I have to substitute the gluOrtho2D call with either gluPerspective or glFrustum. Unfortunately whatever I try is useless.
This is my initialization code:
// set the background color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
/// set the foreground (pen) color
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);*/
// set the foreground (pen) color
glColor4f(1.0f, 1.0f, 1.0f, 0.02f);
// enable blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// enable point smoothing
glEnable(GL_POINT_SMOOTH);
glPointSize(1.0f);
// set up the viewport
glViewport(0, 0, 400, 400);
// set up the projection matrix (the camera)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluOrtho2D(-2.0f, 2.0f, -2.0f, 2.0f);
gluPerspective(45.0f, 1.0f, 0.1f, 100.0f); //Sets the frustum to perspective mode
// set up the modelview matrix (the objects)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while to draw I do this:
glClear(GL_COLOR_BUFFER_BIT);
// draw some points
glBegin(GL_POINTS);
// go through the equations many times, drawing a point for each iteration
for (int i = 0; i < iterations; i++) {
// compute a new point using the strange attractor equations
float xnew=z*sin(a*x)+cos(b*y);
float ynew=x*sin(c*y)+cos(d*z);
float znew=y*sin(e*z)+cos(f*x);
// save the new point
x = xnew;
y = ynew;
z = znew;
// draw the new point
glVertex3f(x, y, z);
}
glEnd();
// swap the buffers
glutSwapBuffers();
the problem is that I don't visualize anything in my window. It's all black. What am I doing wrong?
The name "gluOrtho2D" is a bit misleading. In fact gluOrtho2D is probably the most useless function ever. The definition of gluOrtho2D is
void gluOrtho2D(
GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top )
{
glOrtho(left, right, bottom, top, -1, 1);
}
i.e. the only thing it does it calling glOrtho with default values for near and far. Wow, how complicated and ingenious </sarcasm>.
Anyway, even if it's called ...2D, there's nothing 2-dimensional about it. The projection volume still has a depth range of [-1 ; 1] which is perfectly 3-dimensional.
Most likely the points generated lie outside the projection volume, which has a Z value range of [0.1 ; 100] in your case, but your points are confined to the range [-1 ; 1] in either axis (and IIRC the Z range of the strange attractor is entirely positive). So you have to apply some translation to see something. I suggest you choose
near = 1
far = 10
and apply a translation of Z: -5.5 to move things into the center of the viewing volume.
For my project i needed to rotate a rectangle. I thought, that would be easy but i'm getting an unpredictable behavior when running it..
Here is the code:
glPushMatrix();
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(width_sprite_, 0);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(width_sprite_, height_sprite_);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0, height_sprite_);
glEnd();
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
The problem with that, is that my rectangle is making a translation somewhere in the window while rotating. In other words, the rectangle doesn't keep the position : vec_vehicle_position_.x and vec_vehicle_position_.y.
What's the problem ?
Thanks
You need to flip the order of your transformations:
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
becomes
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
To elaborate on the previous answers.
Transformations in OpenGL are performed via matrix multiplication. In your example you have:
M_r_ - the rotation transform
M_t_ - the translation transform
v - a vertex
and you had applied them in the order:
M_r_ * M_t_ * v
Using parentheses to clarify:
( M_r_ * ( M_t_ * v ) )
We see that the vertex is transformed by the closer matrix first, which is in this case the translation. It can be a bit counter intuitive because this requires you to specify the transformations in the order opposite of that which you want them applied in. But if you think of how the transforms are placed on the matrix stack it should hopefully make a bit more sense (the stack is pre-multiplied together).
Hence why in order to get your desired result you needed to specify the transforms in the opposite order.
Inertiatic provided a very good response. From a code perspective, your transformations will happen in the reverse order they appear. In other words, transforms closer to the actual drawing code will be applied first.
For example:
glRotate();
glTranslate();
glScale();
drawMyThing();
Will first scale your thing, then translate it, then rotate it. You effectively need to "read your code backwards" to figure out which transforms are being applied in which order. Also keep in mind what the state of these transforms is when you push and pop the model-view stack.
Make sure the rotation is applied before the translation.