How to determine a full-window rectangle in OpenGL - opengl

That's problem: I'm currently in OpenGL eye-space, now I want make a black rectangle to cover all window's area. How can I determine a exactly X, Y, Z position to do this?
Update
Or can someone tell me how can I determine the X, Y (top-left) of window when we have a Z value?

You can try to calculate a rectangle that fits the camera exactly and go from there. To do that, you would need to take into account the projection matrix and calculate an inverse.
However, there is a simpler method. All you have to do is to change the camera temporarily, so that you know exactly how to draw the rectangle. A simple enough camera is the default orthogonal camera, with simple limits(from -1 to 1). The following does that:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUAD);
glVertex2f(-1.f, -1.f);
glVertex2f(1.f, -1.f);
glVertex2f(1.f, 1.f);
glVertex2f(-1.f, 1.f);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

Related

How to place coordinates > 100.0f in opengl?

When I place coordinates like this:
display(){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, 360.0f);
drawTeapot();
glutSwapBuffers();
}
The teapot is not visible and I want it visible at 360.0f.
I am using this for init,
init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, width/height, -1000, 1000);
}
It's not a case placing coordinates > 100.0f. For starters your furstrum is wrong as the zNear value should be > 0. There is no negative region of a viewing frustrum :).
The translation you are doing on the ModelView matrix is the wrong way. i.e invert the z translation to -360.0f.
See here for more information on OpenGL axis. If you translate an object n-units to the left, from the camera's point of view you have moved it n-units to the right.
your zNear plane shouldn't be negative
gluPerspective(45, width/height, 0.1, 1000);
have you tried placing the teapot at -360 ? . are you sure your view is looking towards +z and not -z
whats your scaling of the teapot?. Maybe it's just too tiny to be seen so far away

How can I define starting position of glutWireCube?

I am rather new to programming so I may not use the correct terminology. I am trying to create a dog out of only glutwirecubes, however I cannot figure out how to define a starting position for the back legs, nor can I figure out how to close the space between my 'shoulder' and 'elbows'. I have each body part assigned to rotate by key press. I also realize that my use of glPushMatrix and glPopMatrix may not be correct as I do not fully understand how the matrix stack is saved/loaded.
glPushMatrix();
glTranslatef(-1, 0, 0);
glRotatef((GLfloat)body,1, 0, 0);//sets rotations about x,y,z axis
glTranslatef(1, 0, 0);
glPushMatrix();
glScalef(2.0, 0.4, 0.5);//sets dimensions of cube
glutWireCube(2.0);//sets scale of wire cube
glPopMatrix();
glPopMatrix();
glPushMatrix();
glTranslatef(-1, 0, 0);
glRotatef((GLfloat)shoulder, 0, 0, 1);//sets rotations about x,y,z axis
glTranslatef(1, 0, 0);
glPushMatrix();
glScalef(1.5, 0.4, 0.5);//sets dimensions of cube
glutWireCube(.75);//sets scale of wire cube
glPopMatrix();
glTranslatef(1,0,0);
glRotatef((GLfloat)elbow,0,0,1);//sets rotations about x,y,z axis
glTranslatef(1,0,0);
glPushMatrix();
glScalef(1.5,0.4,0.5);//sets dimensions of cube
glutWireCube(.75);//sets scale of wire cube
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
The picture is the position I am aiming for, however my cubes always start oriented horizontally.
with glTranslate right before, as for its friends !
For instance you might translate so that the center is now at the corner, so that your rotations rotate around this new handle.

OpenGL change background without changing perspective of previously drawn pictures

So I draw an 'I' and use gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f), and the I is moderate size. Then I add a drawScene() function which draw the background with gradient color, and then the 'I' becomes super big. I guess it is because I change matrix mode to GL_PROJECTION and GL_MODELVIEW in drawScene(), and those change the perspective maybe? I guess glPushMatrix() and glPopMatrix() are needed to reserve matrix status, but I have hard time finding where to put them. So how can I make the 'I' look normal size? Here are my drawI() and drawScene():
void drawI(int format)
{
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[2][0], point[2][1]);
glVertex2f(point[1][0], point[1][1]);
glVertex2f(point[12][0], point[12][1]);
glVertex2f(point[10][0], point[10][1]);
glEnd();
glBegin(format);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[11][0], point[11][1]);
glVertex2f(point[12][0], point[12][1]);
glEnd();
glBegin(format);
glVertex2f(point[9][0], point[9][1]);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[4][0], point[4][1]);
glVertex2f(point[6][0], point[6][1]);
glColor3f(1, 0.5, 0);
glVertex2f(point[7][0], point[7][1]);
glVertex2f(point[8][0], point[8][1]);
glEnd();
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[5][0], point[5][1]);
glVertex2f(point[6][0], point[6][1]);
glVertex2f(point[4][0], point[4][1]);
glEnd();
}
void drawScene()
{
glBegin(GL_QUADS);
//red color
glColor3f(1.0,0.0,0.0);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
//blue color
glColor3f(0.0,0.0,1.0);
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
}
Thanks a lot!
So I take glMatrixMode() and glLoadIdentity() out of drawScene() and drawI() and put them in display(). I changed drawScene() and drawI() above, and here is my display()
void display()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.f,1.f,0.001f,30.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f);
drawI(GL_TRIANGLE_FAN);
glutSwapBuffers();
}
The normal way to do this (in a 3D mode) is in your code, before you call drawI or drawScene would be:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, aspect, near, far); // fov is camera angle in degrees, aspect is width/height of your viewing area, near and far are your near and far clipping planes.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
In your 2D rendering, you probably don't need the call to gluPerspective, but these calls should be done in your code before you call drawI or drawScene. Do this and delete the glMatrixMode() and glLoadIdentity() calls from drawI and drawScene.
Edit:
If your "I" is still too big, there are a number of things you could do, but you should probably be operating in 3D (giving a Z coordinate also).
You could scale the object:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
glScalef(0.5, 0.5, 0.5);
You could move the camera further back (you'll need to include the gluPerspective() call as well):
gluLookAt(0.0,0.0,50.0,0.0,0.0,0.0,0.0,1.0,0.0);
Perhaps the easiest way to control the rendered image size in a 3D mode is to both move the camera (eye) back a way and then control the image size by changing the camera aperture angle (fov in the gluPerspective() call). A wider fov will shrink the rendered image; a smaller fov will enlarge it.
I don't know what the values for your coordinates are in drawI since they're variables, but a camera position of 3.0, an fov of 70.0 and an aspect of 1 should give you left, right, top and bottom clipping planes of about +/- 2.1 at Z = 0.
If you kept everything else the same and moved the camera to 50.0, the clipping planes would be at about +/- 35.0, so your "I" would occupy a much smaller portion of the viewing area.
If you then left the camera position at 50.0, but changed the fov to 40.0, the clipping planes would be at about +/- 18.2. Your "I" would fill a larger area than it did at cameraZ = 50.0, fov = 70.0, but a smaller area than cameraZ = 3.0, fov = 70.0.
You can play with camera position and fov to get the image size you want, or you could just scale the image. I like to keep camera position constant and change the fov. If I provide a function that changes the fov based on user input (maybe a mouse scroll), it's a good way to provide a zoom in/out effect.
BTW, in your original code, if you called:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
Then later in DrawI or drawScene call:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
You've trashed the matrix loaded by your earlier call to gluLookAt().

OpenGL: GL_QUADS does not draw square

I'm trying to draw a square on the screen but it clearly draws a rectangle.
This is my render code:
glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(0,0,-0.1);
glBegin(GL_QUADS);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(1,1,0);
glVertex3f(0,1,0);
glEnd();
SDL_GL_SwapBuffers();
And OpenGL Init code:
glClearColor(0,0,0,0.6f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30,640.0/480.0,.3f,200.0);
glMatrixMode(GL_MODELVIEW);
Why is this happening?
I don't see anywhere in your code where you have set-up the glViewport. I will rather write something like this in your init method:
glViewport(0,0,640,480); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(30.0f,(GLfloat)640/(GLfloat)480,0.3f,200.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity();
also check the second Nehe tutorial it will help you to start with OpenGL for very basic stuff like drawing primitives such as triangle, square etc...
Try using gluOrtho2D to generate a correct orthogonal projection matrix, in your case gluOrtho2D(0,640,0,480), this is assuming you want a square in 2D and not 3D.
This will of course change your coordinate system from (0,1),(0,1) to (0,640),(0,480).

Draw camera position in specific view port

Most of this code should be fairly self explanatory. I got an display function and my view port function. There are two modes which is 4 small view ports in the window or one large.
I got one camera which can be moved and if in 4 view port mode just 3 fixed angles. The thing is I want the free moving cameras position to be displayed in the 3 other view ports. I tried doing it by drawing spheres using opengl but the problem is that then the position gets draw in the free roaming camera too as it shows the same scene.
It doesn't have to be a sphere, just something simple that represents the cameras spacial position in these three other views.
Drawing the scene once with camera object showing for the three viewports, render to texture. Clear and draw scene without camera object render to texture and then stitch these together before actually drawing the scene seems like a lot o work for something that should be easy.
void display(int what)
{
if(what==5){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camControll();}
if(what==1){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(75,15,-5,0,5,-5,0,1,0);}
if(what==2){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,110,0,0,0,0,1,0,0);}
if(what==3){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, float(320) / float(240), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camControll();}
if(what==4){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(185,75,25,0,28,0,0,1,0);}
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
drawScene();
drawCamera();
glutSwapBuffers();
}
void viewport(){
glEnable(GL_SCISSOR_TEST);
if(!divided_view_port)
{
glViewport(0, 0, w, h);
glScissor(0,0,640,480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 100.0f);
display(5);
}
else
{
////////////////////// bottom left - working
glViewport(0, 0, w/2, h/2);
glScissor(0,0,w/2,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 300.0f);
display(1);
//////////////////////
////////////////////// top right - working
glViewport(w/2, h/2, w/2, h/2);
glScissor(w/2,h/2,w/2,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 300.0f);
display(2);
//////////////////////
////////////////////// bottom right -working
glViewport(w/2, 0, w/2, h/2);
glScissor(w/2,0,w/2,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 300.0f);
display(3);
////////////////////////
////////////////////////// top left
glViewport(0, h/2, w/2, h/2);
glScissor(0,h/2,w/2,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 300.0f);
display(4);
///////////////////////////
}
glDisable(GL_SCISSOR_TEST);
glMatrixMode(GL_MODELVIEW);
}
So what I basically need is to hide this object in specific viewport.
Why not make that single Sphere object (or the entity responsible for drawing the sphere) aware of the "current viewport" (which happens to be the what variable in your code) and let it be invisible if it's the given viewport?
This solution exactly corresponds to the logic involved here sounds both simple and correct.
A more general solution would be to give each "camera" a GUID and make it available for the entity responsible for drawing Cameras to check the GUID of the "camera" bound to the viewport which is being rendered at the moment. If they happen to be equal, ignore the camera object during this draw pass.
I think that should be easy if you would just draw point, because if you want to see point in viewport, its center have to be in viewport, otherwise nothing of it is displayed even if you set huge point size. Then you have 2 options to eliminate flickering effect (as when you put 2 squares in the very same possition they will flicker one over another). You can just move that point little behind camera, or use nonzero value for near clipping plane in glFrustrum/gluPerspective call.. and well if you update point position every time you move camera you have no chance of seeing that point in your moving camera and you can use single scene.
And second option, I don't know if you can update just single viewport, but maybe just setting scene, displaying it to moving camera, drawing camera position and displaying it for other 3 viewports should be easy also..
Why don't you draw the sphere behind the moving camera's near plane? That should ensure that the moving camera doesn't see the sphere at all, but its position is clearly marked for the others.