Display error when moving the camera in opengl - c++

I have a problem in my project, when I move the camera in a location near the image for me is perfect, but as far I move or rotate the camera, it gives me error like this.
I do not know where my error is. How can I correct this?
http://nr7.upanh.com/b5.s32.d2/b7f577d38c0b23cbb35ca367e253b716_50312137.orr.png
http://nr9.upanh.com/b2.s11.d1/0be16f4300e3a84aba3a56e5e2bf008d_50312139.perfec.png
code:
ButtonEndRollVV KeyPessUp;
VeKhungCanh Draw;
GLint ListDraw[100];
void glintIn()
{
glutWarpPointer(400,300);
KeyPessUp.lastx=400;
KeyPessUp.lasty=300;
KeyPessUp.xrot=ROLL_X;
KeyPessUp.yrot=ROLL_Y;
KeyPessUp.xpos=-DEFAUTCAMERAX;
KeyPessUp.ypos=-DEFAUTCAMERAY;
KeyPessUp.zpos=-DEFAUTCAMERAZ;
/////////////////////////////////set defual/////////////////////////////////////
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);// Enables Depth Testing
glClearDepth(1.0f); // Depth Buffer Setup
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClearStencil(0);//gia phong bo dem dat no bang 0
glEnable(GL_STENCIL_TEST);//kich hoat bo dem stencil
////////////////////////////////create list grid///////////////////////////////
ListDraw[0]=glGenLists(1);
glNewList(ListDraw[0],GL_COMPILE);
{
Draw.CreateKhongGian();
}
glEndList();
/////////////////////////////////create cong hang hai//////////////////////////
ListDraw[1]=glGenLists(1);
glNewList(ListDraw[1],GL_COMPILE);
{
Draw.CreateCongHangHai();
}
glEndList();
/////////////////////////////create hang giao/////////////////////////////////
ListDraw[2]=glGenLists(1);
glNewList(ListDraw[2],GL_COMPILE);
{
Draw.CreateHangGiao();
}
glEndList();
//////////////////////////////////anh sang va thong so vat lieu////////////////////////////
float Al[4] = {0.6f, 0.6f, 0.6f, 1.0f };
glLightfv( GL_LIGHT0, GL_AMBIENT, Al );
float Dl[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glLightfv( GL_LIGHT0, GL_DIFFUSE, Dl );
float Sl[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glLightfv( GL_LIGHT0, GL_SPECULAR, Sl );
float Am[4] = {0.6f,0.6f, 0.6f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT, Am );
float Dm[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_DIFFUSE, Dm );
float Sm[4] = {1.0f, 1.0f, 1.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_SPECULAR, Sm );
glMaterialf(GL_FRONT, GL_SHININESS, 45);
glColorMaterial(GL_FRONT, GL_DIFFUSE);//bo cai nay neu bumapping
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity ();
glPushMatrix();
glRotatef(KeyPessUp.xrot,1.0,0.0,0.0);
glRotatef(KeyPessUp.yrot,0.0,1.0,0.0);
glTranslatef(KeyPessUp.xpos,KeyPessUp.ypos,KeyPessUp.zpos);
glCallList(ListDraw[0]);//draw grid
glColor3f(1,1,0);
glCallList(ListDraw[1]);//draw Cong Hang Hai pt parabol:
glCallList(ListDraw[2]);//draw Hang Giao
glPopMatrix();
glFinish();
glutSwapBuffers();
}
void resize(int w,int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//SIZE_KHUNG_CANH*2
float DefaultFus=0.001f;
glFrustum (-DefaultFus, DefaultFus, -DefaultFus, DefaultFus, DefaultFus,SIZE_KHUNG_CANH*3 );
glMatrixMode (GL_MODELVIEW);
glutPostRedisplay();
KeyPessUp.sizeH=h;
KeyPessUp.sizeW=h;
}
void idle()
{
if(KeyPessUp.keyStates[GLUT_KEY_UP]==true)
{
float xrotrad, yrotrad;
yrotrad = (KeyPessUp.yrot / 180 * pi);
xrotrad = (KeyPessUp.xrot / 180 * pi);
KeyPessUp.xpos -= float(sin(yrotrad)/SPEED) ;
KeyPessUp.zpos += float(cos(yrotrad)/SPEED) ;
if(DISABLEUPDOWNCAMERA==0)
KeyPessUp.ypos += float(sin(xrotrad)/SPEED) ;//bỏ đi nếu nhập vai
}
if(KeyPessUp.keyStates[GLUT_KEY_LEFT]==true)
{
float xrotrad, yrotrad;
yrotrad = ((KeyPessUp.yrot+90) / 180 * pi);
xrotrad = ((KeyPessUp.xrot) / 180 * pi);
KeyPessUp.xpos += float(sin(yrotrad)/SPEED) ;
KeyPessUp.zpos -= float(cos(yrotrad)/SPEED) ;
if(DISABLEUPDOWNCAMERA==0)
KeyPessUp.ypos -= float(sin(xrotrad)/SPEED) ;//bỏ đi nếu nhập vai
}
if(KeyPessUp.keyStates[GLUT_KEY_DOWN]==true)
{
float xrotrad, yrotrad;
yrotrad = (KeyPessUp.yrot / 180 * pi);
xrotrad = (KeyPessUp.xrot / 180 * pi);
KeyPessUp.xpos += float(sin(yrotrad)/SPEED);
KeyPessUp.zpos -= float(cos(yrotrad)/SPEED) ;
if(DISABLEUPDOWNCAMERA==0)
KeyPessUp.ypos -= float(sin(xrotrad)/SPEED); //bỏ đi nếu nhập vai
}
if(KeyPessUp.keyStates[GLUT_KEY_RIGHT]==true)
{
float xrotrad, yrotrad;
yrotrad = ((KeyPessUp.yrot+90) / 180 * pi);
xrotrad = ((KeyPessUp.xrot) / 180 * pi);
KeyPessUp.xpos -= float(sin(yrotrad)/SPEED);
KeyPessUp.zpos += float(cos(yrotrad)/SPEED) ;
if(DISABLEUPDOWNCAMERA==0)
KeyPessUp.ypos += float(sin(xrotrad)/SPEED);//bỏ đi nếu nhập vai
}
glutPostRedisplay();
}
void KeyPess(int Key,int x,int y)
{
if(KeyPessUp.acted==0)
{
glutIdleFunc(idle);
KeyPessUp.acted=1;
}
KeyPessUp.keyStates[Key]=true;
}
void KeyUp(int Key,int x,int y)
{
int check=0;
KeyPessUp.keyStates[Key]=false;
for(int i=0;i<255;i++)
{
if(KeyPessUp.keyStates[i]==true)
{
check=1;
}
}
if(KeyPessUp.acted==1&&check==0)
{
glutIdleFunc(NULL);
KeyPessUp.acted=0;
}
}
void KeyExit(unsigned char Key,int x,int y)
{
if(Key==27)
{
exit(0);
}
}
void MouseMove(int x,int y)
{
int xpoint=x-KeyPessUp.lastx;
int ypoint=y-KeyPessUp.lasty;
KeyPessUp.lastx=x;
KeyPessUp.lasty=y;
KeyPessUp.yrot += xpoint*.3;
KeyPessUp.xrot += ypoint*.3;
if (KeyPessUp.xrot >=89) KeyPessUp.xrot = 89;
if (KeyPessUp.xrot <= -89) KeyPessUp.xrot =-89;
if (KeyPessUp.yrot >360) KeyPessUp.yrot -= 360;
if (KeyPessUp.yrot < -360)KeyPessUp.yrot += 360;
glutPostRedisplay();
if(x>450 || x<350 ||y>350 || y<250)
{
glutWarpPointer(400,300);
KeyPessUp.lastx=400;
KeyPessUp.lasty=300;
}
}
int main(int argc,char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("De Tai Nghien Cuu Khoa Hoc");
glintIn();
glutDisplayFunc(display);
glutReshapeFunc(resize);
glutSpecialFunc(KeyPess);
glutSpecialUpFunc(KeyUp);
glutKeyboardFunc(KeyExit);
glutPassiveMotionFunc(MouseMove);
glutMotionFunc(MouseMove);
glutSetCursor(GLUT_CURSOR_NONE);
glewInit();
if(ENDABLE_FULL_SCREEN==TRUE)
glutFullScreen();
glutMainLoop();
return 0;
}

float DefaultFus=0.001f;
glFrustum (-DefaultFus, DefaultFus, -DefaultFus, DefaultFus, DefaultFus,SIZE_KHUNG_CANH*3 );
That's your problem right there: The near clipping place distance is very small compared to the scale to the scene. However the bigger the "scene scale"/"near clip" ratio is, the lower is the effective Z-buffer resolution.
Solution: Choose the near clip plane distance as large, i.e. far away as possible. Ideally you choose the value dynamically depending on the contents of the visible scene and the position of the view point.

Related

Multiple spotlights in opengl doesn't work

I'm using opengl for educational purposes, but I'm having trouble creating multiple spotlights to represent street lamps. I use an iterator to create several however in the end only the last spotlight gets the light, I believe the problem is in the addlight method however I do not know what is happening.
In image below you can see happen.
https://imgur.com/Y77eHln
#include "CreateLamps.h"
std::vector<SpotLight> lamp;
CreateLamps::CreateLamps(int number) {
for (int i = 0; i < number; i++) {
SpotLight *spot = new SpotLight(-8.0f, 5.f, (i*10) + 30.0f, 1.f);
lamp.push_back(*spot);
}
}
void CreateLamps::Add() {
std::vector<SpotLight>::iterator it = lamp.begin();
while (it != lamp.end())
{
glPushMatrix();
glTranslatef(1, 0, 30.0);
glTranslatef(it->position[0], it->position[3] * 3, it->position[2]);
glRotatef(100.f, -5.0, -10, 0);
it->addlight();
it->draw();
it++;
glPopMatrix();
}
}
#include "SpotLight.h"
using namespace std;
GLfloat target[3] = { 0.0f, 0.0f, 0.0f };
GLfloat color[3] = { 1.0f, 1.0f, 1.0f };
GLfloat cutoff(5.0f);
GLfloat exponent(15.0f);
SpotLight::SpotLight(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
position[0] = x;
position[1] = y;
position[2] = z;
position[3] = w;
direction[0] = target[0] - position[0];
direction[1] = target[1] - position[1];
direction[2] = (target[2] - position[2]);
}
void SpotLight::addlight() {
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, color);
glLightfv(GL_LIGHT1, GL_SPECULAR, color);
glLightfv(GL_LIGHT1, GL_POSITION, position);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, cutoff);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, exponent);
}
void SpotLight::draw() {
if (!glIsEnabled(GL_LIGHT1))
return;
glPushMatrix();
GLfloat up[3] = { 0, 1, 0 };
lookAt(position, target, up);
GLfloat ambient[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat diffuse[4] = { 0.01f, 0.01f, 0.01f, 1.0f };
GLfloat specular[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat shininess = 32.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
glutSolidCone(0.3, 0.6, 10, 10);
glPushMatrix();
glTranslatef(0, 0, 0.1f);
glutSolidCylinder(0.2, 0.39, 10, 10);
glPopMatrix();
glDisable(GL_LIGHTING);
glColor3fv(color);
glutSolidSphere(0.2, 100, 100);
glEnable(GL_LIGHTING);
glPopMatrix();
}
void SpotLight::normalize(const GLfloat* vec, GLfloat* output)
{
GLfloat length = sqrtf(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
output[0] /= length;
output[1] /= length;
output[2] /= length;
}
void SpotLight::cross(const GLfloat* vec1, const GLfloat* vec2, GLfloat * output) {
output[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
output[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
output[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
}
void SpotLight::lookAt(GLfloat* eye, GLfloat* center, GLfloat* up)
{
GLfloat f[3] = { center[0] - eye[0],
center[1] - eye[1],
center[2] - eye[2] };
normalize(f, f);
GLfloat u[3];
normalize(up, u);
GLfloat s[3];
cross(f, u, s);
normalize(s, s);
cross(s, f, u);
normalize(u, u);
}
void drawScene() {
glPushMatrix();
glTranslatef(pointlight.position[0], pointlight.position[1], pointlight.position[2]);
pointlight.addLight();
glPopMatrix();
// Draw road
glPushMatrix();
glScalef(10, 10, 8.5);
glTranslatef(-0.018f, 0, 0.75);
glRotatef(180.f, 0, 1, 0);
models[0]->renderTheModel();
glPopMatrix();
//Draw Car Model
glPushMatrix();
glMultMatrixf(carros[0]->local);
carros[0]->draw();
glPopMatrix();
//Draw spotlights
glPushMatrix();
lamps->Add();
glPopMatrix();
}
You are only ever setting LIGHT1, which means only 1 light is going to have been enabled (the last one). If you specify GL_LIGHT0 + index, you'll be able to enable more.
void SpotLight::addlight(int index) {
glEnable(GL_LIGHT0 + index);
glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, color);
glLightfv(GL_LIGHT0 + index, GL_SPECULAR, color);
glLightfv(GL_LIGHT0 + index, GL_POSITION, position);
glLightfv(GL_LIGHT0 + index, GL_SPOT_DIRECTION, direction);
glLightf(GL_LIGHT0 + index, GL_SPOT_CUTOFF, cutoff);
glLightf(GL_LIGHT0 + index, GL_SPOT_EXPONENT, exponent);
}
And then you simply need to pass the index in when enabling
void CreateLamps::Add() {
std::vector<SpotLight>::iterator it = lamp.begin();
while (it != lamp.end())
{
glPushMatrix();
glTranslatef(1, 0, 30.0);
glTranslatef(it->position[0], it->position[3] * 3, it->position[2]);
glRotatef(100.f, -5.0, -10, 0);
it->addlight(it - lamp.begin());
it->draw();
it++;
glPopMatrix();
}
}
Just be aware that you might run out of lights after 8, so you might want to check the value of GL_MAX_LIGHTS...
int numLights = 0;
glGetIntegerv(GL_MAX_LIGHTS, &numLights);
std::cout << "GL_MAX_LIGHTS " << numLights << std::endl;
Presumably you are drawing the road after drawing all of the lights.
Your code does this:
For each light:
Set light 1 according to that light's parameters
Draw the shape of the light itself
Draw the road.
When the road gets drawn, light 1 is set up with the parameters of the last light that was drawn. So it uses these light parameters to draw the road. You overwrote all the parameters of the other lights already.
If you want to draw the road with all the lights, then all the lights have to be set up when you draw the road. Not just the last one.
Note that you can only set up 8 lights at once in OpenGL. If have more than 8 lights pointing at the road, you will have to split up the road into different sections so that each section has up to 8 lights.
Standard disclaimer in case you aren't aware already: You are using old-style (fixed-function) OpenGL which has been superseded by shader-based OpenGL (version 3 and 4). This API is okay for simple programs but it won't let you use the full flexibility and performance of your graphics card.

Trouble drawing Sierpinski with OpenGL

I am trying to generate the Sierpinski Gasket using a function that draws dot patterns and will generate the gasket.
But when I compile and run the program it displays nothing but black screen. What's causing the problem?
Here is my code:
#include <Windows.h>
#include <gl/GL.h>
#include <glut.h>
void myInit(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
class GLintPoint {
public:
GLint x, y;
};
int random(int m) {
return rand() % m;
}
void drawDot(GLint x, GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void Sierpinski(void) {
GLintPoint T[3] = {{ 10, 10 }, {300, 30}, {200, 300}};
int index = random(3);
GLintPoint point = T[index];
for (int i = 0; i < 1000; i++)
{
index = random(3);
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot(point.x, point.y);
}
glFlush();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 150);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(drawDot);
myInit();
glutMainLoop();
}
If you want to draw black dots on a white background, then you have to clear glClear the background:
glClear( GL_COLOR_BUFFER_BIT );
Note, glClearColor sets the color which is used to clear the view port, but doesn't clear anything itself.
Your code should look somehow like this:
void drawDot(GLint x, GLint y)
{
glVertex2i(x, y);
}
void Sierpinski(void) {
GLintPoint T[3] = {{ 10, 10 }, {300, 30}, {200, 300}};
int index = random(3);
GLintPoint point = T[index];
glClearColor(1.0, 1.0, 1.0, 1.0); // set up white clear color
glClear( GL_COLOR_BUFFER_BIT ); // clear the back ground (white)
glMatrixMode( GL_MODELVIEW );
glPushMatrix(); // setup model matrix
glScalef( 1.5f, 1.5f, 1.0f ); // scale the point distribution
glColor3f( 0.0f, 0.0f, 0.0f ); // set black draw color
glPointSize( 5.0f ); // set the size of the points
glBegin(GL_POINTS);
for (int i = 0; i < 1000; i++)
{
index = random(3);
point.x = (point.x + T[index].x) / 2;
point.y = (point.y + T[index].y) / 2;
drawDot(point.x, point.y);
}
glEnd();
glPopMatrix(); // reset model matrix
glFlush();
}

OpenGL with two loops, one loop is not working

My OpenGL program is not working properly. Inside the drawScene() function I created two loops. One loop for GL_LINES another loop for GL_POINTS. The GL_LINES loop works fine but GL_POINTS loop doesn't work. Any help appreciated.
#include <iostream>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define PI 3.14159265
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}
//Initializes 3D rendering
void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //Enable color
glClearColor(0.7f, 0.9f, 1.0f, 1.0f); //Change the background to sky blue
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
float _angle = 0.0f;
float _cameraAngle = 0.0f;
float x = -1.5;
float y = -0.5;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLineWidth (9.0f);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
double r = 0.5;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glPointSize (7.0f);
glBegin(GL_POINTS);
glColor3f(0.0f, 1.0f, 0.0f);
double r = 1.0;
for(int c = 0;c<=360;c++){
double y = r*cos (c*PI/180);
double x = r*sin (c*PI/180);
glVertex3d(x,y,-5.0);
//glVertex3d(0.0,0.0,-5.0);
}
glEnd();
glutSwapBuffers();
//glutPostRedisplay();
}
void update(int value) {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
glutPostRedisplay();
glutTimerFunc(60, update, 0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
//Create the window
glutCreateWindow("two circle");
initRendering();
//Set handler functions
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25, update, 0); //Add a timer
glutMainLoop();
return 0;
}
Right now, you're declaring the variable r in two places: where you set double r = 0.5; and at double r = 1.0;
Try changing it to:
double r = 0.5;
//First loop
r = 1.0;
//Second loop

Animation in Open GL

I never got the concept down on how to get an animation working in OpenGL. I was working on his project trying to get it to work but never got the skier to move. Trying to figure out how to get this fixed.
#include "../shared/gltools.h" // OpenGL toolkit
#define PI 3.14159265
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
bool lookUp;
bool setback;
bool lookDown;
bool lookLeft;
bool lookRight;
bool walkForward;
bool walkBackward;
bool strafeLeft;
bool strafeRight;
float xTranslation;
float yTranslation;
float zTranslation;
float yRotationAngle;
float zRotationAngle;
float xRotationAngle;
int mouseLastx;
int mouseLasty;
float sunRotationAngle=0;
float sunRadius = 150.0;
float day=0;
float dusk=1;
// Light values and coordinates
GLfloat lightPos[] = { 0.0f, 30.0f, 0.0f, 1.0f };
GLfloat lightPos2[] = { 0.0f, 0.0f, 40.0f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat specular2[] = { 0.0f, 1.0f, 0.0f, 1.0f};
GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f};
GLfloat diffuse2[] = { 0.0f, 0.3f, 0.0f, 1.0f};
GLloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};
GLfloat spotDir[] = { 0.0f, 0.0f, -1.0f };
void mouseMovement(int x, int y)
{
int mouseDiffx=x-mouseLastx;
int mouseDiffy=y-mouseLasty;
mouseLastx=x;
mouseLasty=y; //set lasty to the current y position
xRotationAngle += (GLfloat) mouseDiffy;
yRotationAngle += (GLfloat) mouseDiffx;
if (xRotationAngle>=90)
xRotationAngle=90;
if (xRotationAngle<=-90)
xRotationAngle=-90;
//cout << "x:" << x << "y:" << y << endl;
}
void drawcabin()
{
glColor3ub(0, 0, 0);
glBegin(GL_TRIANGLES);
//glTranslatef(0,-5,0); // move view left
//glNormal3f(-3,0.7,-1.7);
//glutSolidCube(5.0f);
glNormal3d(0,0.7,0.7);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glNormal3d(2,-1,1);
glVertex3d(0,6,0);
glVertex3d(-3,3.5,-2);
glVertex3d(2,3.5,-2);
glTranslatef(0,-5,0); // move view left
glNormal3d(-3,0.7,-1.7);
glEnd();
glColor3ub(185, 0, 0);
glutSolidCube(5.0f);
}
void drawskislope()
{
glColor3ub(0, 0, 0);
glBegin(GL_QUADS);
glTranslatef(0,-5,90); // move view left
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
glVertex3d(10,0,5);
glVertex3d(10,.5,5);
glVertex3d(15,.5,5);
glVertex3d(15,0,5);//small square
glColor3ub(201, 192, 187);
glVertex3d(11.5,.5,5);
glVertex3d(13.5,.5,5);
glVertex3d(13.5,-10,5);
glVertex3d(11.5,-10,5);
//slope start
glTranslatef(0,-5,0); // move view left
// glNormal3d(-3,0.7,-1.7);
glEnd();
}
void drawskier()
{
float a = -5;//maybe
float b = 29;
float c = 27;
float d = 28.25;
float e = 28.5;
glBegin(GL_QUADS);
glTranslatef(0,-5,0); // move view
glColor3ub(185, 122, 87);
glNormal3d(0,5,1);
//Do While loop
// do
// {
// to move skier do a loop and update a in the translate
glTranslatef(0,a,0); // move view
glVertex3d(c,0,5);//10
glVertex3d(c,.1,5);//10
glVertex3d(b,.1,5);//15
glVertex3d(b,0,5);//skis on skier
glNormal3d(0,5,1);
glVertex3d(d,0,5);
glVertex3d(d,1.35,5);
glVertex3d(e,1.35,5);
glVertex3d(e,0,5);//body on skier
glutSwapBuffers;
// }while(b>15); //try to animate
glEnd();
glFlush();
b=b-1;
c=c-1;
d=d-1;
e=e-1;
glutPostRedisplay();
glTranslatef(30,3,0); // move view left
glColor3ub(168, 220, 109);
glutSolidSphere(.5,7,8); //sphere-head
glPushMatrix();
glTranslatef(3.5,-100,2);
glutSolidSphere(25,15,15); //sphere
glPopMatrix();
}
void updatescene()
{
}
///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
GLUquadricObj *pObj; // Quadric Object
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
GLfloat horizontalMovement=1;
GLfloat verticalMovement=0;
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
horizontalMovement=cos(xRotationAngle*PI/180);
verticalMovement=-sin(xRotationAngle*PI/180);
if (lookDown)
{
xRotationAngle+=1;
if (xRotationAngle>=90)
xRotationAngle=90;
}
if (lookUp)
{
xRotationAngle-=1;
if (xRotationAngle<=-90)
xRotationAngle=-90;
}
if (lookRight)
{
yRotationAngle+=1;
if (yRotationAngle>=360)
yRotationAngle=0;
}
if (lookLeft)
{
yRotationAngle-=1;
if (yRotationAngle<=-360)
yRotationAngle=0;
}
if (walkForward)
{
zTranslation+=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation-=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation-=verticalMovement;
}
if (walkBackward)
{
zTranslation-=cos(yRotationAngle*PI/180)*horizontalMovement;
xTranslation+=sin(yRotationAngle*PI/180)*horizontalMovement;
yTranslation+=verticalMovement;
}
if (strafeRight)
{
zTranslation+=cos((yRotationAngle+90)*PI/180);
xTranslation-=sin((yRotationAngle+90)*PI/180);
}
if (strafeLeft)
{
zTranslation-=cos((yRotationAngle+90)*PI/180);
xTranslation+=sin((yRotationAngle+90)*PI/180);
}
if (setback)
{
zTranslation=0;
xTranslation=0;
yTranslation=0;
}
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(xRotationAngle,1,0,0);
glRotatef(zRotationAngle,0,0,1);
glRotatef(yRotationAngle,0,1,0);
glTranslatef(xTranslation,yTranslation,zTranslation);
//glRotatef(-15,1,0,0);
//glRotatef(90,0,1,0);
glTranslatef(0,-0.50,-10);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
sunRotationAngle++;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(0,0,0);
glLineWidth(2);
//snow
glColor3ub(255, 255, 255);
glBegin(GL_QUADS);
glNormal3f(0,1,0);
for (int i=-100;i<=200;i+=10) //x
for (int j=-100;j<=200;j+=10)//z
{
float y1=(-j)*.25;
float y2=(-j+10)*.25;
glVertex3d(i+10,y2,-100);
glVertex3d(i,y2,-100);
glVertex3d(i,y1,-100);
glVertex3d(i+10,y1,-100);
}
glEnd();
glPushMatrix();
glTranslatef(-10,14,-50);
drawcabin();
drawskislope();
drawskier();
glPopMatrix();
// Flush drawing commands
glutSwapBuffers();
glutPostRedisplay();
//GLfloat horizontalMovement=1;
// GLfloat verticalMovement=0;
}
void TimerFunction(int value)
{
// Redraw the scene with new coordinates
glutPostRedisplay();
updatescene();
glutTimerFunc(16,TimerFunction, 1);
}
///////////////////////////////////////////////////////////
// Setup the rendering context
void SetupRC(void)
{
lookUp=false;
lookDown=false;
lookLeft=false;
lookRight=false;
walkForward=false;
walkBackward=false;
strafeLeft=false;
strafeRight=false;
yRotationAngle=0;
xRotationAngle=0;
zRotationAngle=0;
xTranslation=0;
yTranslation=0;
zTranslation=0;
// White background
glClearColor(0.5f,0.95f, 1.0f, 1.0f );
// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
// Set color shading model to flat
glShadeModel(GL_SMOOTH);
// Clock wise wound polygons are front facing, this is reversed
// because we are using triangle fans
glFrontFace(GL_CCW);
glEnable (GL_DEPTH_TEST);
}
void ChangeSize(int w, int h)
{
//GLfloat nRange = 100.0f;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
GLfloat fAspect;
fAspect = (GLfloat)w / (GLfloat)h;
//glOrtho(-10,10,-10,10,0,1000);
gluPerspective(45,fAspect,0.1,1000);
// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=true;
if(key == GLUT_KEY_DOWN)
lookDown=true;
if(key == GLUT_KEY_LEFT)
lookLeft=true;
if(key == GLUT_KEY_RIGHT)
lookRight=true;
// Refresh the Window
glutPostRedisplay();
}
void SpecialKeysUp(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
lookUp=false;
if(key == GLUT_KEY_DOWN)
lookDown=false;
if(key == GLUT_KEY_LEFT)
lookLeft=false;
if(key == GLUT_KEY_RIGHT)
lookRight=false;
// Refresh the Window
glutPostRedisplay();
}
void keyboardFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=true;
break;
case 's':
walkBackward=true;
break;
case 'a':
strafeLeft=true;
break;
case 'd':
strafeRight=true;
break;
case 'r':
setback=true;
break;
default:
break;
}
}
void keyboardUpFunc(unsigned char key, int x, int y)
{
switch(key)
{
case 'w':
walkForward=false;
break;
case 's':
walkBackward=false;
break;
case 'a':
strafeLeft=false;
break;
case 'd':
strafeRight=false;
break;
default:
break;
}
}
///////////////////////////////////////////////////////////
// Main program entry point
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("Assignment 2");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
glutSpecialUpFunc(SpecialKeysUp);
glutKeyboardUpFunc(keyboardUpFunc);
glutKeyboardFunc(keyboardFunc);
glutPassiveMotionFunc(mouseMovement);
SetupRC();
glutMainLoop();
return 0;
}
My general approach is to use a glutTimerFunc() callback to post a redisplay event every 16 milliseconds or so (~60 FPS).
Then in the glutDisplayFunc() callback you can grab the new GLUT_ELAPSED_TIME to calculate a delta-time (dt) from the last frame.
With dt in hand you can update any number of variables such as angles or translation offsets. You'll want to use dt instead of fixed increment values to decouple your animation speed from your framerate.
Then back in the glutDisplayFunc() callback you draw a new frame using the updated state variables.
This is an example that uses the method above to rotate a square at about 30 degrees per second:
#include <GL/glut.h>
float angle = 0;
void update( const double dt )
{
// in degrees per second
const float SPEED = 30.0f;
// update angle
angle += ( SPEED * dt );
}
void display()
{
// GLUT_ELAPSED_TIME is in milliseconds
static int prvMs = glutGet( GLUT_ELAPSED_TIME );
const int curMs = glutGet( GLUT_ELAPSED_TIME );
// dt is in seconds
const double dt = ( curMs - prvMs ) / 1000.0;
prvMs = curMs;
// update world state
update( dt );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// reset projection/modelview matrices each frame;
// this makes sure we have a known-good matrix
// stack each time through display()
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// draw rotated square
glRotatef( angle, 0, 0, 1 );
glBegin( GL_QUADS );
glColor3ub( 255, 0, 0 );
glVertex2i( -1, -1 );
glVertex2i( 1, -1 );
glVertex2i( 1, 1 );
glVertex2i( -1, 1 );
glEnd();
glutSwapBuffers();
}
void timer( int value )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 600, 600 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}

Why is this program not moving the camera correctly?

While pressing the down key, I expect the teapot to be drawn away as farther, yet it remains the same size. Why?
Note: this is a homework thing, I'm not allowed to use glTranslate.
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <GL/gl.h>
void display(void);
class Camera {
public: float eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ;
float aimX, aimY, aimZ;
Camera () {
eyeX = 0.0f ;
eyeY = 0.0f;
eyeZ = 0.5f ;
centerX = 0.0f;
centerY = 0.0f;
centerZ = 0.0f;
upX = 0.0f;
upY = 1.0f;
upZ = 0.0f;
}
void move_camera(double speed) {
aimX = centerX - eyeX;
aimY = centerY - eyeY;
aimZ = centerZ - eyeZ;
eyeX += aimX * speed;
eyeY += aimY * speed;
eyeZ += aimZ * speed;
centerX += aimX *speed;
centerY += aimY *speed;
centerZ += aimZ *speed;
}
};
Camera camera;
void init(void){
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void specialKeys(int key, int x, int y){
if (key==GLUT_KEY_UP){
camera.move_camera(0.03f);
display();
}
if (key==GLUT_KEY_DOWN){
camera.move_camera(-0.03f);
display();
}
}
void reshape(int w, int h){
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (float)w/(float)h, 0.0f, 200.0f); // fov, aspect ratio, ncp, fcp
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(camera.eyeX, camera.eyeY, camera.eyeZ, // eye
// camera.centerX, camera.centerY, camera.centerZ, // center
// camera.upX, camera.upY, camera.upZ // up
//
//);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camera.eyeX, camera.eyeY, camera.eyeZ, // eye
camera.centerX, camera.centerY, camera.centerZ, // center
camera.upX, camera.upY, camera.upZ // up
);
//glTranslatef(0.0,0.0,1.0f);
glutWireTeapot(0.5f);
glutSwapBuffers();
glFlush();
}
int main (int argc, char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
//glutCreateWindow(argv[0]);
glutInitWindowPosition(500,200);
glutInitWindowSize(800,600);
glutCreateWindow("fgh");
init();
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glutIdleFunc(display);
glutMainLoop();
return 0;
}
Your projection matrix is damaged.
gluPerspective(45.0f, (float)w/(float)h, 0.0f, 200.0f); // fov, aspect ratio, ncp, fcp
The third argument is the distance of the near clipping plane. It cannot be equal to 0 as that would imply that you need an inifinite-precision depth buffer. Make it 0.1 or 0.01.
I was missing the call to glutReshapeFunc(reshape);. That's it.