Moving the camera to the left and right based on mouse movement - c

I know this has been asked before, but I have yet to find an answer that works in my case.
Basically, I want the camera to move left and right based on the mouse cursor position. The more the mouse is to the left, the more the camera turns to the left. So it should be possible to turn around and move in the reverse direction. How do I do this?
This is my camera position:
GLfloat cameraPosition[] = { 0.0, 0.0, 3.5 };
GLfloat lx = 0.0; GLfloat ly = 0.0;
This is my projection matrix:
// set to projection mode
glMatrixMode(GL_PROJECTION);
// clear any previous transformations
glLoadIdentity();
// set the perspective
gluPerspective(45, (float)windowWidth / (float)windowHeight, 0.1, 20);
In the myDisplay function, this how I set the camera position:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// set the camera position
gluLookAt(cameraPosition[0], cameraPosition[1], cameraPosition[2],
lx, ly, cameraPosition[2] - 100,
0, 1, 0);
What should I do in the glutPassiveMotionFunc function?

Most probably you need to do something like this
glRotatef(-yAngle, 0.0f, 1.0, 0.0f);
glRotatef(-xAngle, 1.0f, 0.0f, 0.0f);
glTranslatef(cameraPosition[0], cameraPosition[1], cameraPosition[2])
instead of gluLookAt(). Try it out, maybe it will solve your problem.

Related

how to use glTranslatef,glScalef,glRotatef in openGL

I just want something like this video : https://youtu.be/dGWtdYlryQQ
It shows how to use glTranslate, glRotate, gluOrtho2d in OpenGL ,but it's not guide me anything
In my case, I draw a diamond instead of triangle and here is my condition
condition :
when I press r or R on the keyboard the diamond will rotate clockwise
when I press t or T on the keyboard the diamond will move to the right side
when I press + on the keyboard the diamond will bigger
here is my code :
#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <iostream>
using namespace std;
float angle = 0;
float t,s=0.5,m=0;
void myinit(void){
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
}
void keyboard(unsigned char key, int x, int y){
if(key==27)
{
exit(0);
}else if(key == 82 || key == 114){
angle-=0.1;
glRotatef(angle,0,0,1);
glutPostRedisplay();
}else if(key == 84 || key == 116 )
{
t+=0.01;
glTranslatef(t,0,0);
glutPostRedisplay();
}else if(key == 43){
s+=0.01;
// m-=0.1;
// glTranslatef(m,m,0.0);
glScalef(s,s,0);
glutPostRedisplay();
}
(void)(x);
(void)(y);
}
void hut(void){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.5,0.4,0.0);
glVertex3f(0.42,0.5,0.0); // GREEN
glVertex3f(0.44,0.5,0.0);
glColor3f(1.5,1.0,0.0);
glVertex3f(0.46,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.57,0.5,0.0);
glEnd();
glFlush();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.44,0.55,0.0);
glVertex3f(0.42,0.5,0.0);
glVertex3f(0.46,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.48,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.48,0.55,0.0);
glVertex3f(0.46,0.5,0.0);
glVertex3f(0.50,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.52,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.52,0.55,0.0);
glVertex3f(0.50,0.5,0.0);
glVertex3f(0.54,0.5,0.0);
glColor3f(0.25,0.0,0.0);
glVertex3f(0.56,0.55,0.0);
glEnd();
glColor3f(1.5,1.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.56,0.55,0.0);
glVertex3f(0.54,0.5,0.0);
glVertex3f(0.57,0.5,0.0);
glEnd();
glFlush();
}
int main(int argc,char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(640,480);
glutCreateWindow("Polygon with viewport");
myinit();
glutDisplayFunc(hut);
glutKeyboardFunc(keyboard);
glutMainLoop();
}
And here is my output : https://drive.google.com/file/d/14HHRiCbOHK9ZSZtDOqSl4GP4aSy7UQLh/view?usp=sharing
It it’s not similar to this https://youtu.be/dGWtdYlryQQ
The operations on the matrix stack are based on one another. The reference system of each operation is the current transformation.
See the documentation of glTranslate:
glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, [...]
and see the documentation of glRotate:
glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.
This means that glRotate does a rotation around the origin of the current local system.
While glRotatetf followed by glTranslatef results in:
glTranslatef followed by glRotatef results in:
Since you object is displaced, you have to translate it in that way, that the rotation point is placed in the origin:
glTranslatef(-0.5f, -0.5f, 0.0f);
Then you can rotate it:
glRotatef(angle, 0.0f, 0.0f, 1.0f);
And move it back:
glTranslatef(0.5f, 0.5f, 0.0f);
Note, on the Fixed Function Pipeline stack you have to "push" this operations in the reverse order. Further you should use the GL_MODELVIEW matrix stack. (See glMatrixMode.)
Remove all the matrix operations from the function keyboard and add the following to the function hut:
void hut(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(t, 0.0f, 0.0f);
glTranslatef(0.5f, 0.5f, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(s, s, 0.0f);
glTranslatef(-0.5f, -0.5f, 0.0f);
.....
Further, your object gets destroyed by the aspect ratio of the view. This can be fixed by taking care of the aspect ratio when setting up the projection matrix:
float w = 640.0f;
float h = 480.0f;
glOrtho(0.0,w/h,0.0,1.0,-1.0,1.0);
glRotate rotates about the origin (0,0). Given your projection matrix (that you set with glOrtho) the origin is initially at the lower left corner of your screen, unless you use glTranslate. Your diamond is not centered at the origin, but positioned somewhat away from it. What you need to do is change the vertex values in your void hut(void) method to make the diamond centered at 0,0. Then use glTranslate to move the render origin (and thus also the diamond) to where you want it, then use glRotate.

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).

OpenGL - Rotating moon around sun without it spinning?

I'm working on a graphics model of the Moon rotating around the Earth. Right now, the Moon spins on its y axis while rotating around the Earth. How can I prevent the Moon from spinning but still allow it to orbit? Here's the code..
Edit:
Added an animation video to demonstrate problem:
http://www.youtube.com/watch?v=ltGV4pXD5Cs
void DrawInhabitants(GLint nShadow)
{
static GLfloat yRot = 0.0f; // Rotation angle for animation
if(nShadow == 0)
{
yRot += 0.2f;
}
// Draw the randomly located spheres
glBindTexture(GL_TEXTURE_2D, textureObjects[MOON_TEXTURE]);
glPushMatrix();
glTranslatef(0.0f, 0.1f, -2.5f);
glPushMatrix();
glRotatef(-yRot * 2.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(1.0f, 0.0f, 0.0f);
gltDrawSphere(0.1f,21, 11);
glPopMatrix();
if(nShadow == 0)
{
// Torus alone will be specular
glMaterialfv(GL_FRONT, GL_SPECULAR, fBrightLight);
}
glRotatef(-yRot, 0.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, textureObjects[EARTH_TEXTURE]);
gltDrawSphere(0.3f, 21, 11);
glMaterialfv(GL_FRONT, GL_SPECULAR, fNoLight);
glPopMatrix();
}
The problem is that you're rotating the coordinate system in order to place the moon in its desired relative position. This rotation is global so it affects the orientation of the moon as well. You need to undo the rotation after translating, so you have "translation sandwich"
rotate a
translate
rotate -a

OpenGL Lighting Failing when Scaling

I have to read a 3D object from an ASE file. This object turns to be too big for the world I have to create, therefore, I must scale it down.
With its original size, it is properly lighted up.
However, once I scale it down, it becomes oversaturated.
The world is centered around (0, 0, 0) and it is 100 meters long (y axis) and 50 meters wide (x axis), my upVector is (0, 0, 1). There are two lights, light0 in (20, 35, 750) and light1 in (-20, -35, 750).
Relevant parts of the code:
void init(void){
glClearColor(0.827, 0.925, 0.949, 0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
GLfloat difusa[] = { 1.0f, 1.0f, 1.0f, 1.0f}; // white light
glLightfv(GL_LIGHT0, GL_DIFFUSE, difusa);
glLightfv(GL_LIGHT1, GL_DIFFUSE, difusa);
loadObjectFromFile("objeto.ASE");
}
void display ( void ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX, eyeY, eyeZ, atX, atY, atZ, 0.0, 0.0, 1.0);
GLfloat posicion0[] = { 20.0f, 35.0f, 750.0f, 1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, posicion0);
GLfloat posicion1[] = { -20.0f, -35.0f, 750.0f, 1.0f};
glLightfv(GL_LIGHT1, GL_POSITION, posicion1);
glColor3f(0.749, 0.918, 0.278);
glPushMatrix();
glTranslatef(0.0, 0.0, 1.5);
//Here comes the problem
glScalef(0.08, 0.08, 0.08);
glBegin(GL_TRIANGLES);
for(int i = 0; i < numFaces; i++){
glNormal3d(faces3D[i].n.nx, faces3D[i].n.ny, faces3D[i].n.nz);
glVertex3d(vertex[faces3D[i].s.A].x, vertex[faces3D[i].s.A].y, vertex[faces3D[i].s.A].z);
glVertex3d(vertex[faces3D[i].s.B].x, vertex[faces3D[i].s.B].y, vertex[faces3D[i].s.B].z);
glVertex3d(vertex[faces3D[i].s.C].x, vertex[faces3D[i].s.C].y, vertex[faces3D[i].s.C].z);
}
glEnd();
glPopMatrix();
glutSwapBuffers();
}
Why does lighting fail when the object is scaled down?
The problem you're running into is, that scaling the modelview matrix also influences the "normal matrix" normals are transformed with. The "normal matrix" is actually the transpose of the inverse of the modelview matrix. So by scaling down the modelview matrix, you're scaling up the normal matrix (because of the modelview inversion step used to obtain it).
Because of that the transformed normals must be rescaled, or normalized if the scale of the modelview matrix is not unitary. In fixed function OpenGL there are two methods to do this: Normal normalization (sounds funny, I know) and normal rescaling. You can enable either with
glEnable(GL_NORMALIZE);
glEnable(GL_RESCALE_NORMALS);
In a shader you'd simply normalize the transformed normal
#version ...
uniform mat3 mat_normal;
in vec3 vertex_normal;
void main()
{
...
vec3 view_normal = normalize( mat_normal * vertex_normal );
...
}
Depending on the setting of GL_NORMALIZE and GL_RESCALE_NORMALS, your normals can be transformed by the OpenGL-Pipeline.
Start with glEnable(GL_NORMALIZE) and see if that solves your problem

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 );

Resources