Je me suis programmé hier soir ce petit prog permetant un mouvement de camera style doom-like.
J'ai eu la merveilleuse idée de venir lire ce forum après l'avoir programmé... ce qui fait que je n'ai pas pensé au matrice... (argghhhh
)
Bref, ma méthode me donne pas mal de bug graphique et j'aimerais savoir ou sont les problèmes. A moins que vous me disiez tout simplement de passer aux matrices
voici mon code:
**************************************************
**************
#include<gl/glut.h>
#include<stdio.h>
#include<math.h>
int LightPos[4] = {0,0,3,1}; //x,y,z,ponctuelle(1) ou directionnelle(0)
int MatSpec [4] = {1,1,1,1};
int WindowName;
double a=0;
const double PI = acos (-1.0);
double rad;
double px=0.0, py=1.0, pz=20.0;
double vx=0.0, vy=0.0, vz=0.0;
double savex=vx, savey=vy;
double angle_x, angle_y;
double sensibilite=1.0;
double vitesse=0.1; //sensibilite de la souris
void Reshape(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, float(width)/float(height), 0, 100);
glMatrixMode(GL_MODELVIEW); //Optionnel
}
void Draw()
{
glMaterialiv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec);
glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,100);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(px,py,pz,vx,vy,vz,0,1,0);
glRotated(a,0,1,0);
glLightiv(GL_LIGHT0,GL_POSITION,LightPos);
glRotated(-a,0,1,0);
glutSolidSphere(1,50,50);
a +=0.1 ;
glBegin (GL_LINES);
glVertex3i(0,0,-40); glVertex3i(0,0,40);
glVertex3i(0,-40,0); glVertex3i(0,40,0);
glVertex3i(-40,0,0); glVertex3i(40,0,0);
glEnd();
glutSwapBuffers();
glutPostRedisplay(); //Demande de recalculer la scène
}
void InitGL()
{
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL); //Active le coloriage
glEnable(GL_LIGHTING); //Active l'éclairage
glEnable(GL_LIGHT0); //Allume la lumière n°1
rad = sensibilite/180.0 * PI;
angle_x = 90.0/180.0 * PI;
angle_y = 90.0/180.0 * PI;
vx = 10*cos(angle_x);
vy = 10*cos(angle_y);
}
double AngleXY() //renvoie l'angle en radian
{
double res;
double k = vx-px;
double m = vz-pz;
if (k!=0 || m!=0) {
res = fabs(k) / sqrt(k*k+m*m);
if (k<0) {
if (m<0) res = PI - acos(res);
else res = PI + acos(res);
}
else if (m<0) res = acos(res);
else res = 2*PI - acos(res);
}
else {
if (py == 0) printf("error angleXY\n" );
else res = acos(1);
}
return res;
}
double AngleXZ() //renvoie l'angle en radian
{
double res=0;
double k = vy-py;
double l = vz-pz;
if (k!=0 || l!=0) {
res = fabs(k) / sqrt(k*k+l*l);
if (k<0) {
if (l<0) res = PI - acos(res);
else res = PI + acos(res);
}
else if (l<0) res = acos(res);
else res = 2*PI - acos(res);
}
else {
if (pz == 0) printf("error angleXZ\n" );
else res = acos(1);
}
return res;
}
void GestionSpecialClavier(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_LEFT: {
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
double angle_xy = AngleXY();
px -= vitesse*sin(angle_xy);
vx -= vitesse*sin(angle_xy);
if (angle_xy != 0) {
pz -= vitesse*cos(angle_xy);
vz -= vitesse*cos(angle_xy);
}
vitesse = 0.05;
break;
}
case GLUT_KEY_UP: {
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
double angle_xy = AngleXY();
double angle_xz = AngleXZ();
if (angle_xz != PI/2) {
py += vitesse*cos(angle_xz);
vy += vitesse*cos(angle_xz);
}
pz += vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
vz += vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
if (angle_xy != 0) {
px += vitesse*cos(angle_xy)*fabs(sin(angle_xz));
vx += vitesse*cos(angle_xy)*fabs(sin(angle_xz));
}
vitesse = 0.05;
break;
}
case GLUT_KEY_RIGHT: {
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
double angle_xy = AngleXY();
px += vitesse*sin(angle_xy);
vx += vitesse*sin(angle_xy);
if (angle_xy !=0) {
pz += vitesse*cos(angle_xy);
vz += vitesse*cos(angle_xy);
}
vitesse = 0.05;
break;
}
case GLUT_KEY_DOWN: {
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) vitesse = 0.4;
double angle_xy = AngleXY();
double angle_xz = AngleXZ();
if (angle_xz != PI/2) {
py -= vitesse*cos(angle_xz);
vy -= vitesse*cos(angle_xz);
}
pz -= vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
vz -= vitesse*fabs(sin(angle_xy))*-sin(angle_xz);
if (angle_xy != 0) {
px -= vitesse*cos(angle_xy)*fabs(sin(angle_xz));
vx -= vitesse*cos(angle_xy)*fabs(sin(angle_xz));
}
vitesse = 0.05;
break;
}
case GLUT_KEY_PAGE_UP: {
sensibilite += 0.1;
rad = sensibilite/180.0 * PI;
break;
}
case GLUT_KEY_PAGE_DOWN:{
sensibilite -= 0.1;
rad = sensibilite/180.0 * PI;
break;
}
case GLUT_KEY_HOME: {
vx = 0; vy = 0; vz = 0;
break;
}
}
}
void GestionClavier(unsigned char key, int x, int y)
{
if (key=='a') {
printf ("angle avec le plan xy: %f\n",AngleXY()/PI * 180.0);
printf ("angle avec le plan xz: %f\n",AngleXZ()/PI * 180.0);
}
if (key=='c') printf("coord: (%f,%f,%f)\n",px,py,pz);
if (key=='r') {
px = -px; py = -py; pz = -pz;
vx = -vx; vy = -vy; vz = -vz;
}
if (key=='v') printf("vision: (%f,%f,%f)\n",vx,vy,vz);
if (key==27) exit(0);
}
void GestionMouvementSouris(int x, int y)
{
int save;
if (x < savex)
{
save = x;
while (x < savex) {
angle_x -= rad;
vx = 10*cos(angle_x) + px;
vz = 10*sin(angle_x) + pz;
++x;
}
savex = save;
}
else if (x > savex)
{
save = x;
while (x > savex) {
angle_x += rad;
vx = 10*cos(angle_x) + px;
vz = 10*sin(angle_x) + pz;
--x;
}
savex = save;
}
else if (y < savey)
{
save = y;
while (y < savey) {
angle_y += rad;
vy = 10*cos(angle_y) + py;
vz = 10*sin(angle_y) + pz;
++y;
}
savey = save;
}
else
{
save = y;
while (y > savey) {
angle_y -= rad;
vy = 10*cos(angle_y) + py;
vz = 10*sin(angle_y) + pz;
--y;
}
savey = save;
}
}
int main (int argc, char *argv[ ], char *envp[ ])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(800,600); glutInitWindowPosition (100,100);
WindowName = glutCreateWindow("Ma première fenêtre OpenGL !" );
// glutFullScreen(); //Optionnel
glutReshapeFunc(Reshape);
glutDisplayFunc(Draw);
InitGL();
glutKeyboardFunc(GestionClavier);
glutSpecialFunc(GestionSpecialClavier);
glutPassiveMotionFunc(GestionMouvementSouris);
glutMainLoop();
return 0;
}
****************************************************************
Majca