I can't figure out how to convert mouse drag into rotation around Ox and Oy of the image plane.
I followed the first answer from here and I'm storing the modelView matrix in an array, and updating it every time the mouse moves. alpha and beta are proportional to the mouse increments from the previous position.
This code updates the rotation when the mouse moves:
glLoadMatrixf(currentModelViewMatrix);
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
I tried the solution from the end of this explanation but didn't make any difference.
Only the rotation given by beta is absolute, the rotation given by alpha is around an axis in the model which turns when there is a rotation around the first axis. I don't know how to make the second rotation be absolute. The way it is right now doesn't seem intuitive to a user.
edit:
The increment code:
GLfloat currentModelViewMatrix[16];
GLfloat whole[16];
void glob()
{
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX,whole);
alpha=beta=0;
}
And before every model, the matrix is loaded:
glLoadMatrixf(whole);
The full code:
#include "math.h"
#include "string.h"
#include "stdio.h"
#include "GL/freeglut.h"
#include "GL/gl.h"
#include "GL/glu.h"
float alpha,beta;
void key(int key, int x, int y)
{ printf("%d",key);
switch(key)
{ case GLUT_KEY_RIGHT:
printf("right\n");
break;
case GLUT_KEY_LEFT:
printf("left\n");
break;
case GLUT_KEY_UP:
printf("top\n");
break;
case GLUT_KEY_DOWN:
printf("bottom\n");
break;
}
glutPostRedisplay();
fflush(stdout);
}
void otherkeys(unsigned char key,int x,int y)
{ printf("%c\n",key);
fflush(stdout);
switch(key)
{ case '+':
printf("plus\n");
break;
case '-':
printf("minus\n");
break;
case 'w':
alpha+=10;
break;
case 's':
alpha-=10;
break;
case 'd':
beta+=10;
break;
case 'a':
beta-=10;
break;
}
glutPostRedisplay();
}
void drawCube()
{ int i,j,d;
glBegin(GL_LINES);
for(i=0;i<8;i++)
{ for(j=i+1;j<8;j++)
{ d=j^i;
if(d==1||d==2||d==4)
{ glVertex3i(i%2,i/2%2,i/4%2 );
glVertex3i(j%2,j/2%2,j/4%2 );
}
}
}
glEnd();
}
GLfloat currentModelViewMatrix[16];
GLfloat whole[16];
void glob()
{
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX,whole);
alpha=beta=0;
}
void renderFunction()
{ int i;
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glRotatef(angle2,0.0,0.0,1.0);
gluPerspective(60, 1.333, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glColor3f(1.0,0.0,0.0);
for(i=1;i<8;i++)
{
glLoadMatrixf(whole);
glTranslatef(i*2.0,0,0);
drawCube();
}
glColor3f(0.0,1.0,0.0);
for(i=1;i<6;i++)
{
glLoadMatrixf(whole);
glTranslatef(0,i*2.0,0);
drawCube();
}
glColor3f(0.0,0.0,1.0);
for(i=0;i<5;i++)
{
glLoadMatrixf(whole);
glTranslatef(0,0,i*2.0);
drawCube();
}
glFlush();
}
/*mouse*/
int prevx,prevy,dx,dy;
void rotate(int dx,int dy)
{ printf("%f %f\n",dy/10.0,dy/10.0);
alpha=dy/2.0;
beta=dx/2.0;
glob();
}
void passive(int x,int y)
{ prevx=x;prevy=y;}
void active(int x,int y)
{ dx=x-prevx;
prevx=x;
dy=y-prevy;
prevy=y;
rotate(dx,dy);
}
void globinit()
{
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glLoadIdentity();
glTranslatef(0,0,-20);
glGetFloatv(GL_MODELVIEW_MATRIX, whole);
}
int main (int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Open GL bla bla");
glutDisplayFunc(renderFunction);
glutIdleFunc(renderFunction);
glutSpecialFunc(key);
glutKeyboardFunc(otherkeys);
glutMotionFunc(active);
glutPassiveMotionFunc(passive);
globinit();
glutMainLoop();
return 0;
}
Try the following:
glLoadIdentity();
glRotatef(beta,0,1,0);
glRotatef(alpha,1,0,0);
glMultMatrixf(currentModelViewMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
Due to the changed order the rotations are performed in the global coordinate system rather than a local one.
Related
So i'm making a game(something similar to a pong)using openGl in cpp , and when i try running the program , the image rendering is too slow ,i feel something is taking a huge toll on my GPU memory ,
(So far i have competed the drawing and movement of the paddle which works fine and the problem arises when the ball is set to motion on the press of a button , Everything slows down after this )
Here i have attached a portion of my code
Point out any deficiencies in my code
#include<stdlib.h>
#include<GL/glut.h>
#include<windows.h>
#include<iostream>
//#include<sstream>
#include<stdio.h>
#include<ctime>
#include<string.h>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
//GLvoid player1_box();
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key){
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
//printf("Inside switch r");
break;
}
glutPostRedisplay();
}
void display()
{
Sleep(2);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
//printf("x move in disp:%1f \n",xmove);
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball(); //To draw the ball
glPopMatrix();
glFlush();
}
void moveBall(){ //glutidlefunction
if(release==1)
{ //Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
Sleep(500);
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,w,h);
//glutPostRedisplay();
//Use the whole window for rendering
}
int main(int argc ,char **argv)
{
//clock_t begin= clock();
char n1,n2;
int ack;
/*printf("The object of Tic Tac Toe is to get three in a row. \n . Players alternate placing Xs and Os(Traingles and Boxes in this version) \n on the game board until either opponent has three \n in a row or all nine squares are filled(Which would be a drawObviously). \n");
printf("\n Press 1 if acknowledged \n");
scanf("%d",&ack);*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(moveBall);
glClearColor(1,1,1,1);
glutMainLoop();
//clock_t end=clock();
}
You're using c++, use C++-style (stdlib.h -> cstdlib) headers.
Apply your projection/modelview matrices each time through display() instead of a reshape callback, helps prevent annoying matrix stack issues.
Don't Sleep(), use a timer/idle callback to glutPostRedisplay(). Bonus points for framerate-independent movement (you can use glutGet(GLUT_ELAPSED_TIME) to calculate delta-t).
Without Sleep() there's no reason to drag windows.h into things.
All together:
#include <GL/glut.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cstring>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
break;
}
}
void display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball();
glPopMatrix();
glFlush();
}
void moveBall()
{
if(release==1)
{
//Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void timer( int value )
{
moveBall();
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
int main(int argc ,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
}
I am trying to move a camera in a 3d space. So far I have had success in moving and rotating the camera using this code:
void specialKeyHandler(int key, int x, int y) {
float fraction = 0.05f;
switch (key) {
case GLUT_KEY_LEFT :
camAngle -= 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_RIGHT :
camAngle += 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_UP :
iX += lX * fraction;
iZ += lZ * fraction;
break;
case GLUT_KEY_DOWN :
iX -= lX * fraction;
iZ -= lZ * fraction;
break;
default:
break;
}
}
Of course I have these variables defined. lX, lY, lZ are for LookAt variables and iX, iY and iZ are for camera's eye.
The camera moves as required, but now I want to attach an object on the "camera's eye" which shall move with the camera. Just like a Weapon in a FPS game.
This is what I have for that:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEarth();
drawWalls();
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX+0.05,iY, iZ-0.05);
glRotatef(camAngle, 0,1,0);
glutWireCone(0.005,0.1,20,20); // object to go with camera
glPopMatrix();
glutSwapBuffers();
}
This code currently does bind the object with the camera while moving up and down. But when I rotate the camera by pressing left and right keys, object stays there and camera moves on its own..
Any solution?
Here's the full opengl code, if anyone wants to run:
#include <GL/glut.h>
#include<iostream>
#include<math.h>
using namespace std;
void display(void);
void reshape(int, int);
void mouseHandler(int button, int state, int x, int y);
void keyBoardHandler(unsigned char c, int x, int y);
void specialKeyHandler(int key, int x, int y);
float angle = 0;
bool camDefault = true, perspectiveOrtho = true;
float iX =0 , iY = -0.8, iZ = 0, lX = 0, lY = -0.8, lZ = -1, uX = 0, uY = 1, uZ = 0;
float camAngle = 0;
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(512, 512);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("FPS Camera");
glutDisplayFunc(display);
glutIdleFunc(display);
//look from negative x axis towards origin. with y on top
glutReshapeFunc(reshape);
glEnable(GL_DEPTH_TEST);
glClearColor(0,0,0,1);
glutMouseFunc(mouseHandler);
glutKeyboardFunc(keyBoardHandler);
glutSpecialFunc(specialKeyHandler);
glutMainLoop();
return 0;
}
void drawEarth() {
glColor3f(0,255,0);
glBegin(GL_QUADS);
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
glEnd();
}
void drawWalls() {
glColor3f(0,0,255);
glBegin(GL_QUADS);
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
glEnd();
glColor3f(0,234,255);
glBegin(GL_QUADS);
glVertex3f(-1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(1,1,1);
glVertex3f(1,-1,1);
glEnd();
}
float unitVector(float dir, float x, float y, float z) {
float sumSqr = pow(x,2) + pow(y,2) + pow(z,2);
return dir / (sqrt(sumSqr));
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEarth();
drawWalls();
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX+0.05,iY, iZ-0.05);
glRotatef(camAngle, 0,1,0);
glutWireCone(0.005,0.1,20,20);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90,1, 0.001, 1000);
gluLookAt(iX,iY,iZ,iX+lX,lY,iZ+lZ,uX,uY,uZ);
glMatrixMode(GL_MODELVIEW);
}
void updateLookAt() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (90, 1 ,0.001, 1000);
gluLookAt(iX,iY,iZ,iX+lX,lY,iZ+lZ,uX,uY,uZ);
glMatrixMode(GL_MODELVIEW);
}
void keyBoardHandler(unsigned char c, int x, int y) {
switch(c) {
case 'f': // go left
iX-=0.01;
lX -= 0.01;
cout<<endl<<"S pressed";
break;
case 's': // go right
iX += 0.01;
lX += 0.01;
break;
case 'e': // go up
iZ += 0.01;
lZ += 0.01;
break;
case 'd': // go down
iZ -= 0.01;
lZ -= 0.01;
break;
default:
break;
}
updateLookAt();
}
void mouseHandler(int button, int state, int x, int y) {
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
if(camDefault) {
glLoadIdentity();
gluLookAt(-1,0,0,0.0,0.0,0.0,0.0,1,0);
camDefault = false;
}
else {
glLoadIdentity();
gluLookAt(0,0,0,0.0,0.0,0.0,0.0,1,0);
camDefault = true;
}
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(perspectiveOrtho) {
gluPerspective (90, 1 ,0.00001, 1000);
perspectiveOrtho = false;
}
else {
glOrtho(-1,1,-1,1, -1,100);
perspectiveOrtho = true;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(camDefault)
gluLookAt(0,0,1,0.0,0.0,0.0,0.0,1,0);
else
gluLookAt(-1,0,0,0.0,0.0,0.0,0.0,1,0);
}
}
void specialKeyHandler(int key, int x, int y) {
float fraction = 0.05f;
switch (key) {
case GLUT_KEY_LEFT :
camAngle -= 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_RIGHT :
camAngle += 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_UP :
iX += lX * fraction;
iZ += lZ * fraction;
break;
case GLUT_KEY_DOWN :
iX -= lX * fraction;
iZ -= lZ * fraction;
break;
default:
break;
}
updateLookAt();
}
You have two problems.
The first problem is on your coordinates system.
When you apply :
glTranslatef(iX+0.05,iY, iZ-0.05);
You place the object at the camera position, and add an offset to see him. But this is in the world coordinates system. So when you rotate the camera, the object doesn't move cause it doesn't follow the camera's coordinates system.
You need to translate to the camera center, rotate the camera, then add the offset.
The second problem is on the rotation. Your "camAngle" variable is in radian, cause you use it with cos() and sin(). But in OpenGL, glRotate take the angle as a degree value. You need to convert this angle in angle : angle *= 180/PI. (180/PI ~= 57.2957795)
Here the corrected display function :
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX,iY,iZ); // Translation to the camera center
glRotatef(-camAngle * 57.2957795, 0,1,0); // Rotate to correspond to the camera
glTranslatef(0.05,0,-0.05); // Offset to draw the object
glutWireCone(0.005,0.1,20,20);
glPopMatrix();
drawEarth();
drawWalls();
glutSwapBuffers();
}
I am trying to move the camera with the use of the keyboard. I am calling the glulookat function in the draw method as follows:
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
Also I have, for example, for moving the position of the camera on the X axis the following code:
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
The posx,posy,posz,lookx,looky,lookz,upx,upy,upz variables are declared as global double variables. I have tried to initialize them in two ways: when declaring them, as well as in the init() method, but with no success. The camera isn't moving, although the program receives the keyboard input properly, as I have tested this aspect separately. Any ideas of what I am doing wrong?
EDIT: I provided the main code for a better understanding:
Outer_space* space;
Light* sceneLight;
Light* sceneLight2;
Light* sceneLight3;
Satelite* satelite1;
double posx=35.0,posy=35.0,posz=35.0,lookx=0,looky=1,lookz=0,upx=0,upy=0,upz=-1;
void init(void) {
//random number generator
srand(time(NULL));
space = new Outer_space(12, 12,12, new Vector3D(0.5f, 0.7f, 0.9f));
sceneLight = new Light(0, 0);
sceneLight->setTranslation(new Vector3D(0, 20, 0));
sceneLight->setConstantAttenuation(0.09f);
sceneLight->setLinearAttenuation(0.08f);
sceneLight2 = new Light(1, 0);
sceneLight2->setTranslation(new Vector3D(20, 0, 0));
sceneLight2->setConstantAttenuation(0.09f);
sceneLight2->setLinearAttenuation(0.08f);
sceneLight3 = new Light(2, 0);
sceneLight3->setTranslation(new Vector3D(0, 0, 20));
sceneLight3->setConstantAttenuation(0.09f);
sceneLight3->setLinearAttenuation(0.08f);
satelite1 = new Satelite(2,new Vector3D(0.2f,0.3f,0.5f));
satelite1->setTranslation(new Vector3D(10,10,10));
satelite1->setRotation(new Vector3D(-90, 0, 0));
satelite1->setScale(new Vector3D(10, 10, 10));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
}
void draw(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0,20,0, 0, 0, 0, 0, 1, 0);
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
space->draw();
sceneLight->draw();
sceneLight2->draw();
sceneLight3->draw();
satelite1->draw();
glPushMatrix();
glRasterPos3f(-8.5, 4, -6);
glutSwapBuffers();
}
void update(void){
glutPostRedisplay();
}
void resize(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
GLfloat aspect = (GLfloat)w / (GLfloat)h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1.0, 60);
}
void keyboard(unsigned char key, int x, int y) {
switch (key)
{
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
void specialKeyboard(int key, int x, int y) {
switch (key)
{
case GLUT_KEY_RIGHT:
posx+=1;
break;
case GLUT_KEY_LEFT:
posx-=1;
break;
case GLUT_KEY_UP:
break;
case GLUT_KEY_DOWN:
break;
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Asteroid Escape");
init();
glutIdleFunc(update);
glutDisplayFunc(draw);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialKeyboard);
glutMainLoop();
return 0;
}
EDIT2:
I have commented out the glPushMatrix(); call from the draw() method and now the camera seems to be moving. What is the explanation?
glPushMatrix is supposed to be followed by glPopMatrix.
It seems that you overflow the matrix stack, did you check glGetError result ?
Besides, jour call to glPushMatrix seems pretty useless like this, what do you expect it to do ?
I've just drawn a 3 dof robot with 3 joints which are revoloute , i've drawn a shere to use as an obstacle which should be constant without any moving but as the gripper of the robot starts to move my obstacle moves too, which shouldnt,2nd problem is : i want to turn arond my robot i did this by arrow keys theres no error but it dosent work.here is my code:
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#define VIEW_TURN_RATE 10
#define GLUT
#define GLUT_KEY
#define GLUT_SPEC
float t1=30;
float t2=45;
float t3=45;
float t4=0;
float t5=0;
float l=1.5;
float h=0.2*l;
double m=0.2;
double n=0.2;
double p=0.2;
float eyex,eyey=0;
float eyez=6;
float lx,ly,lz=0;
int turn = 0, turn1 = 0;
void TurnRight(void)
{
turn = (turn - VIEW_TURN_RATE) % 360;
}
void TurnLeft(void)
{
turn = (turn + VIEW_TURN_RATE) % 360;
}
void TurnForwards(void)
{
turn1 = (turn1 - VIEW_TURN_RATE) % 360;
}
void TurnBackwards(void)
{
turn1 = (turn1 + VIEW_TURN_RATE) % 360;
}
void myidlefunc()
{
if(t1<100)
t1+=2;
else
{
if(t2<150)
t2+=2;
else
{
if(t3<150)
t3+=2;
else
{
if(t4<150)
t4+=2;
else
{
if(t5<120)
t5+=2;
else
{
glutIdleFunc(0);
}
}
}
}
}
glutPostRedisplay();
}
#ifdef GLUT
#ifdef GLUT_SPEC
void
special(int key, int x, int y)
{
int i = 0;
printf("this is special keyboard: %d \n",key);
switch (key) {
/* start of view position functions */
case 'r':{
TurnRight();
i++;
}
break;
case GLUT_KEY_LEFT:{
TurnLeft();
i++;
}
break;
case GLUT_KEY_DOWN:{
TurnForwards();
i++;
}
break;
case GLUT_KEY_UP:{
TurnBackwards();
i++;
}
break;
/* end of view postions functions */
}
if (i)
glutPostRedisplay();
}
#endif
#ifdef GLUT_KEY
void keyboard(unsigned char c,int x,int y)
{
switch(c)
{
case 27:
exit(0);
break;
case 's':
if (t1 < 50) {
t1++;}
break;
case 'S':
//if (t1 < 80) {
t1--;
//}
break;
case 'q':
glutIdleFunc(myidlefunc);
break;
case 'f':
if (t2 < 160) {
t2++;}
break;
case 'F':
t2--;
break;
case 'g':
t3++;
break;
case 'h':
t4++;
break;
case 'k':
t5++;
break;
}
glutPostRedisplay();
}
#endif
#endif
void drawFloor(void)
{
glPushMatrix ();
glBegin(GL_QUADS);
glColor3f(0.0,0.8,0.8);
glVertex3f(-20.0, 0.0, 100.0);
glVertex3f(20.0, 0.0, 100.0);
glVertex3f(20.0, 0.0, -100.0);
glVertex3f(-20.0, 0.0, -100.0);
glEnd();
glPopMatrix ();
glEnable(GL_LIGHTING);
}
void Base(float l)
{
glPushMatrix();
//glColor3f(0.4,0.6,0.5);
glScaled(1.0*l,0.2*l,1.0*l);
glutSolidCube(1);
glPopMatrix();
}
void obst(float radius, int slices, int stacks)
{
glTranslated (0,-0.5,0.0);
glPushMatrix ();
glutSolidSphere (radius,slices,stacks);
glPopMatrix ();
}
void arm(float l,float r,int slices,int stacks,float rotat)
{
float d;
d=0.2*l;
glTranslated (0,l/2+d/2,0);
glPushMatrix ();
glScaled (d/l,1,d/l);
glutSolidCube (l);
glPopMatrix ();
glTranslated (0,l/2,0);
glRotated (rotat,0,0,1);
glPushMatrix ();
glutSolidSphere (r,slices,stacks);
glPopMatrix ();
}
void Base2(float l,float r,int slices,int stacks,float rotat)
{
float d;
d=0.2*l;
glTranslated (d/2,d/2,d/2);
glPushMatrix ();
glScaled (d,d/2,d);
glutSolidCube (2);
glPopMatrix ();
}
void hand(float d,float x)
{
glColor3f(0.0,0.4,0.3);
glRotated(t5,0,1,0);
glPushMatrix ();
glTranslated(0,-d/2+x/2,0);
glScaled(1,x/d,1);
glutSolidCube (d);
glPopMatrix();
glPushMatrix ();
glTranslated(-d/2+x/2,x/2,0);
glScaled (x/(d-x),1,d/(d-x));
glutSolidCube(d-x);
glPopMatrix ();
glPushMatrix ();
glTranslated (d/2-x/2,x/2,0);
glScaled (x/(d-x),1,d/(d-x));
glutSolidCube(d-x);
glPopMatrix ();
}
void display()
{
float l,T,r,x,d;
double radius,height;
int slices, stacks;
l=1.5;
T=30;
d=0.2*l;
x=0.2*d;
r=d/2;
radius=1.0;
height=3;
slices=1000;
stacks=202;
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glPushMatrix ();
//lightning start here
glEnable(GL_LIGHT0);
GLfloat light0_pos []={lx,ly+1,lz+1,1};
GLfloat light0_diffuse []={1,0,0,0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);
GLfloat light0_Ambient []={0,1,1,0};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_Ambient);
gluLookAt(0.2,0.8,0.0,5.0,3.0,5.0,0.0,0.1,0.0);
glLightfv(GL_LIGHT0,GL_POSITION,light0_pos);
glScaled(0.2,0.2,0.2);
glRotated(90,0.0,1.0,0.0);
/* Draw "bottom" of floor in blue. */
glColor3f(0.0, 0.8, 0.8);
drawFloor();
//base
glColor3f(0.0,0.0,0.0);
Base(2);
//base2
glColor3f(1.0,0.0,0.0);
Base2(l,r,60,60,t1);
//arm1
glColor3f(1.0,0.0,0.8);
arm(l,r,60,60,t1);
glColor3f(0.0,1.0,0.0);
arm(l,r,60,60,t2);
glColor3f(1.0,0.8,0.5);
arm(l,r,60,60,t3);
//hand
glTranslated (0,d/2+r,0);
hand(d,x);
//obst
glTranslated (-1,3,0);
glColor3f(0.0,0.0,1.0);
obst(radius,slices,stacks);
//glRotated(0.0,0.0,1.0,0.0);
glPopMatrix ();
glFlush();
glutSwapBuffers();
}
void reshape(int width,int height)
{
float aspect=(float)width/(float)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,width,height);
//glOrtho(-aspect,aspect,-1,+1,-1,+1);
gluPerspective(60.0,0.0,0.0,8);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
//glTranslatef(0.0, 0.0, 0.0); /* viewing transform */
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
glutInitWindowPosition(0,0);
glutInitWindowSize(500,500);
static int window=glutCreateWindow("OPenGL!");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
#ifdef GLUT_SPEC
glutSpecialFunc(special);
#endif
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glutMainLoop();
exit(0);
}
As you are rendering the obstacle last, your modelview matrix has been the recipient of all the transforms up to that point. You need to manage your modelview matrix more carefully using glPushMatrix() and glPopMatrix(). I haven't tested but try a push just before //arm 1 and pop just before your //obst.
I want to move triangle on plane.How will i do it.I am using opengl "glut" and also i want to keep co-ordinate position of triangle.first time it will start at point (0,0,-6) and then when i will press "a" this will move left and when i will press "d" this will move "right".I know the keyoperation definition in opengl of "w" and "s".But my main concern is with movment and knwoing of co-ordinate points.
Thankie
Use global variables to store your programs state. One of these states is the triangle position. Modify this variable in the keyboard handler, then call glutPostRedisplay. In the display function draw the scene according to the program's state.
Important hints: OpenGL is "merely" a sophisticated rasterizer API, which means it "lives for the moment", i.e. you just draw triangles with it, and after you sent the rendering command and they've been processed OpenGL has no "persistency" about the sent geometry and the only trace left are the changes in the framebuffer.
If what you're looking for is more along the lines of "I want to describe a scene consisting of geometric objects and those shall interact through some black box mechanism" you're looking for a so called scene graph, which OpenGL is not (but many scene graphs use OpenGL as a backend).
EDIT: Full example source code
#include <GL/gl.h>
#include <GL/glut.h>
#define ORTHO_SCALE 10.
GLfloat triangle_vertices[] = {
-0.5, 0.0,
0.5, 0.0,
0.0, 1.0
};
struct {
struct {
struct {
GLfloat x, y;
} pos;
GLfloat rot;
} triangle;
} sceneinfo;
void display(void);
void keyboard(unsigned char key, int x, int y);
void special(int key, int x, int y);
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("simple triangle test");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}
void display(void)
{
GLuint win_width, win_height;
GLfloat win_aspect;
win_width = glutGet(GLUT_WINDOW_WIDTH);
win_height = glutGet(GLUT_WINDOW_HEIGHT);
win_aspect = (float)win_width/(float)win_height;
glViewport(0, 0, win_width, win_height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-win_aspect * ORTHO_SCALE,
win_aspect * ORTHO_SCALE,
-ORTHO_SCALE,
ORTHO_SCALE,
-1., 1.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(sceneinfo.triangle.pos.x, sceneinfo.triangle.pos.y, 0.);
glRotatef(sceneinfo.triangle.rot, 0, 0, 1.);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, triangle_vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key) {
case '+':
sceneinfo.triangle.rot += 2.;
break;
case '-':
sceneinfo.triangle.rot -= 2.;
break;
}
glutPostRedisplay();
}
void special(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT:
sceneinfo.triangle.pos.x -= 0.2;
break;
case GLUT_KEY_RIGHT:
sceneinfo.triangle.pos.x += 0.2;
break;
case GLUT_KEY_UP:
sceneinfo.triangle.pos.y += 0.2;
break;
case GLUT_KEY_DOWN:
sceneinfo.triangle.pos.y -= 0.2;
break;
}
glutPostRedisplay();
}