explanation of glFrustum() compared to gluLookAt() - c++

I'm debugging a code where i want to look at a scan of a depth image, but my camera setup doesn't let me see the scan. Thus, i'm playing around with camera setups. I create a huge point at (30,120,800) and i can see it using gluLookAt. What is the according setup for glFrustum(left, right, bottom, top, near, far)? Using my setup, the point should lay exactly in the center, but i cannot see it.
void onDisplay()
{
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDisable(GL_CULL_FACE);
glPushMatrix();
glPointSize( 1111111116.0 );
glColor3f( 0.25f, 0.907, 0.731f );
glLoadIdentity();
// Set the camera
//gluLookAt( 30.f, 120.0f, 800.f, 30.f, 120.0f, 800.f, 0.0f, 1.f, 0.0f); //works
glFrustum( 28, 32, 118, 122, 798, 802);
glBegin( GL_POINTS );
glVertex3f( 30, 120, 800 ); //30,120,800
glEnd();
glPopMatrix();
//glFinish();
//glutSwapBuffers();
glutSwapBuffers();
glutPostRedisplay();
}
int main(int argc, char **argv)
{
// initialize GLUT
glutInitWindowSize(800, 800);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInit(&argc, argv);
glutCreateWindow("HeadPoseDemo");
glutKeyboardFunc (processSpecialKeys);
glutDisplayFunc(onDisplay);
glutMainLoop();
return 0;
}

The devil's in the details: Note how in the documentation they say
nearVal, farVal
Specify the distances to the near and far depth clipping planes. Both distances must be positive.
That's different from the wording they use for the other parameters:
left, right
Specify the coordinates for the left and right vertical clipping planes.
What you're expected to know is that you're looking along the negative z-axis. So my guess is that you're going to see your point when you change it to glVertex3f(30.f, 120.f, -800.f);.

Related

Zooming Issues with glutMouseWheelFunc

I tired implementing a simple zoom in/out using the glutMouseWheelFunc in VC++. I am able to achieve the zooming in/out but while doing so, the axes(GLlines) tend to disappear after zooming more than a certain level.
Am using the glutMouseWheelFunc to increase/decrease z- axis value in glTranslatef.
I have defined 'z' of glTranslatef for as camera distance:
float cDist= 30.0f; // camera distance
Then used it in glTranslatef as,
glTranslatef(0.0f, 0.0f, -cDist);
in display function below.
void display(void) {
glClearColor(0.0, 0.0, 0.0, 1.0); //clear the screen to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//clear the color buffer and the depth buffer
enable();
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -cDist);
glRotatef(xrot, 1.0, 0.0, 0.0);
---------------
glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-500, 0, 0);
glVertex3f(500, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0, -500, 0);
glVertex3f(0, 500, 0);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0, 0, -500);
glVertex3f(0, 0, 500);
glTranslated(-xpos, 0.0f, -zpos); //translate the screento the position of our camera
glColor3f(1.0f, 1.0f, 1.0f);
glutSwapBuffers();
}
Afterwards, I defined wheelfunc as,
void mouseWheel(int button, int dir, int x, int y)
{
if (dir > 0)
{
cDist = cDist++;
}
else
{
cDist= cDist--;
}
return;
}
and called it in main function with glutMouseWheelFunc(mouseWheel);
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Window");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutMotionFunc(mouseMovement);
glutMouseWheelFunc(mouseWheel);---- here
-----
---
glutMainLoop();
return 0;
}
Is this approach of zooming in proper? if not, what could be the alternative ? Also how can I define axes(lines I drew) to full extent of the screen?
thanks for the help. Seems like I missed up setting up proper depth value for gluPerspective. Once I increased the depth value, zoom out/in was working fine

How to display a sphere correctly in openGL

I don't know very much about openGL/glut, but I've used it before successfully for some exceedingly simple things in 2D.
Now I want to be able to draw spheres in 3D. I'm trying to simulate particle collisions, so all I'm really going to need to do on the graphics end is draw spheres.
Here's my abortive attempt
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glutSwapBuffers();
}
void timerProc(int arg)
{
glutTimerFunc(50,timerProc,0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glColor3f(0.0,0.0,0.0); //color = black
glPushMatrix();
glTranslated(0,0,0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50,30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)-80,glutGet(GLUT_SCREEN_HEIGHT)-60);
mainWindow=glutCreateWindow("New Window"); //global variable
WIDTH=glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT=glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glutTimerFunc(50,timerProc,0);
glutMainLoop();
return 0;
}
Hopefully all of my problems stem from one really basic mistake...
For some reason, this creates an oval. And, though the oval is pretty big (maybe about an 1/8th of the screen wide and tall), if I lower the radius down to .73 it vanishes, I'm guessing because it's too small to see.
How would I make it so that this sphere would show up circular like you'd expect, and so that as I can see everything that's happening in a given volume, say a 10x10x10 box, the way you would if you were just standing next to a box of particles that were flying around and peering into it, or a reasonable approximation. Right now it's hard to tell what exactly I'm looking at (I know that I'm standing at 1,1,1 and looking at the origin, but it's hard to grasp exactly what I'm seeing)
Also, occasionally when I run it the whole screen is just black. Then when I clean and build and run again it's fine. Not really a huge concern, but annoying, and I'd love to understand what was going on.
Also, when I the number of slices and stacks was lower, it would look fine if the radius was large, but become extremely distorted when the radius was small, which I thought was very strange...
The main problem you are having here is Z clipping. The initial Z range for the scene is (-1, 1) so you only see a part of the actual sphere and by change in its size you go out of z range.
Image
There are several problems I see in the code.
It is good to get a grasp of how the GLUT workflow actually works.
Lets see what the code does wrong.
Main
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH) - 80,
glutGet(GLUT_SCREEN_HEIGHT) - 60);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
Here you define the display function. It is called every time the window contents has to be invalidated. In this case it is invalidated only at start. The renderScene function does not do anything awesome, just clears the screen. So you get a black screen at the beginning.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
No need for blending at the moment. You can skip that part altogether.
glutTimerFunc(50, timerProc, 0);
Now you set up the timerProc function to be called in 50 milliseconds.
glutMainLoop();
As the documentation states: glutMainLoop enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.
return 0;
}
Render Scene
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This is the only place where you clear the screen. Timer Func does not do this.
glLoadIdentity();
You are reseting the matrices.
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
Setting up the matrices. (One matrix to be precise)
glutSwapBuffers();
And without drawing anything you swap buffers.
}
Scene rendering function is called each time the window frame has to be redrawn.
Timer
This function does rely on the screen being cleared at first by the renderScene.
void timerProc(int arg)
{
glutTimerFunc(50, timerProc, 0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
Not clearing this time. Only setting the color.
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
How to fix it?
Just setup the matrices. With proper Z range.
void resetTransformations() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1000, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
}
void renderScene()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
resetTransformations();
// Just to see some triangles
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(0.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(256, 256);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutMainLoop();
return 0;
}

How to make the background of my texture transparent? (My image is already backgroundless)

I have a backgroundless image of a gun. I am trying to build a first person shooter game with the help of this 2D image of a gun. I have loaded the texture in my program but I am unable to make the background of the gun transparent. Moreover, why should I even have to do that when my image is already backgroundless. I used clippingmagic.com to remove the background of my image. The code is:
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include<SOIL/SOIL.h>
//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
using namespace std;
const float A = 1366.0; //width of the computer screen
const float B = 768.0; //height of the computer screen
//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
int x, int y) { //The current mouse coordinates
switch (key) {
case 27: //Escape key
exit(0); //Exit the program
}
}
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0); //The far z clipping coordinate
}
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0,0.0,-10.0);
//DRAW WALL OF ROOM
glBegin(GL_QUADS);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(-100.0, -100.0, -100.0);
glVertex3f(-100.0, 100.0, -100.0);
glVertex3f( 100.0, 100.0, -100.0);
glVertex3f( 100.0, -100.0, -100.0);
glEnd();
//DRAW GUN
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLuint gun_tex_id = SOIL_load_OGL_texture
(
"GUN.png",
SOIL_LOAD_RGB, //I even tried SOIL_LOAD_AUTO and SOIL_LOAD_RGBA but it didn't help
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_MULTIPLY_ALPHA
);
glBindTexture(GL_TEXTURE_2D, gun_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTranslatef(2.0,0.0,0.0);
glColor3f(1.0,1.0,1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-4.1,-4.15, 0.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 3.0,-4.15, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 3.0, 1.2, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-4.1, 1.2, 0.0);
glEnd();
glDisable(GL_BLEND);
glutSwapBuffers(); //Send the 3D scene to the screen
}
void myinit(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); /* gray background */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( -A/2, A/2, -B/2, B/2, -200, 200);
/* In World coordinates:position the "clipping rectangle" at -A/2, its right edge at +A/2, its bottom edge at -B/2 and its top edge at +B/2 */
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(A, B); //Set the window size
//Create the window
glutCreateWindow("My shooting game");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
myinit();
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}
You can do it using glBlendFunc function.
Try adding the following code snippet before you bind texture to the object.
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Read this for more information.

OpenGL Drawing Axis in Corner

I've been searching on how to draw an Indicator-Axis in my OpenGL scene. The project's nested in a Qt OpenGL widget, but I think the problem is independent of Qt.
I have found on here and forums from years ago that suggest storing the viewport and data, loading new ones for the botttom corner, apply my rotations and draw, then restore the matrices. This seems the most beneficial to me, but I'm guessing I'm still missing some critical info in my OpenGL knowledge.
For now I just have it drawing a red line from -x to x, so I expected to have a red square in the bottom left of the screen:
void GLWidget::drawAxis()
{
float tempPro[16];
float tempMod[16];
glGetFloatv(GL_PROJECTION_MATRIX, &tempPro[0]);
glGetFloatv(GL_MODELVIEW_MATRIX, &tempMod[0]);
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
glPopMatrix();
glViewport(0, 0, 960, 600);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(tempPro);
gluPerspective(45.0f, (960.0/600.0), 0.1f, 400.0f);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(tempMod);
}
Instead I get nothing, just a large empty scene, and I'm unsure how to proceed. My paintGL is essentially:
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Camera.Render();
glTranslatef(0.0, 0.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(50.0f, 0.0f, 50.0f);
glVertex3f(50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, -50.0f);
glVertex3f(-50.0f, 0.0f, 50.0f);
glEnd();
drawAxis();
}
Not calling the draw-axis function still gives me my plane, with it, I get a large blank scene. Am I missing something in how I'm implementing the drawAxis? Should I setup another camera for the function or something like that?
You can use glPushMatrix() and glPopMatrix() to save and restore the state of your Projection and ModelView matrices.
Your not setting up your ModelView matrix to anything useful.
Try something like this:
void GLWidget::drawAxis()
{
glViewport(0, 0, 50, 50);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluPerspective(45.0f, 1.0f, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//This really has to come from your camera....
gluLookAt(10.0f,10.0f,10.0f, 0.0f,0.0f,0.0f, 0.0f,0.1f,0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glEnable( GL_LINE_SMOOTH );
glLineWidth( 1.5 );
glBegin(GL_LINES);
glVertex3f(-1000, 0, 0);
glVertex3f(1000, 0, 0);
glEnd();
//Restore View
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glViewport(0, 0, 960, 600);
}

OpenGL cutting off part of screen

I'm learning OpenGL, and I am reading a book to help me a long. I've followed it through half way and have decided to go off on my own path now that I'm familiar with the basics. I've started to develop an application, the intention is to just show a grid.
I've pretty much nailed it, but when I run my application, part of the grid is cut off. I've attached a condensed version of the code (which has the same result) - does anyone know what I am doing wrong to make it cut off part of the screen? I've tinkered about a lot and I've run through a few values but I just cannot get this thing sorted. Any help or a nudge in the right direction is much appreciated.
Code:
#include <Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "deps\glut\glut.h"
void display();
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("");
glutDisplayFunc(display);
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
// Init
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-8.0, 8.0, -8.0, 8.0, -8.0, 8.0);
glutMainLoop();
return 0;
}
void display() {
float f;
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
// This next bit of code just creates the grid
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(1.0);
for(f=-10.0f;f<10.0f;f++) {
glBegin(GL_LINES);
glVertex3f(f, 0.0f, -10.0f);
glVertex3f(f, 0.0f, 10.0f);
glEnd();
}
glRotatef(90, 0.0, 1.0, 0.0);
for(f=-10.0f;f<10.0f;f++) {
glBegin(GL_LINES);
glVertex3f(f, 0.0f, -10.0f);
glVertex3f(f, 0.0f, 10.0f);
glEnd();
}
// Swap the buffers
glutSwapBuffers();
}
You can't draw outside the unit cube.
Your glOrtho call scales the coordinates so that you can use the range -8...8 for x, y, and z coordinates, but your for loop then tries to use -10...10, which exceeds the range and will be clipped.
You're hitting the Z limits due to the diagonal of a unit cube being sqrt(3) longer than the side. So I suggest you use -14…14 ( = ± round( 8*sqrt(3) ) ) as limits for the near and far plane.