2011-05-04 57 views
0

我想制作一个球体,并把焦点放在中心的相机,有一个矢量(VUP = 0,1,0)。我想改变球面坐标r,theta,phi。在opengl上的球体上的相机 - 旋转和初始窗口的问题

问题是,当我运行的应用程序,球体出现,但是当我按下一个键它消失。 如果我从setupmywindow中删除glMatrixMode(GL_PROJECTION),那么在开始时球体不会出现,但是如果我按下一个键它会出现。然后,按下“r”和“p”,它会改变它的半径,但是按“u”和“f”它只旋转一步。

#define PI 3.1415f 


float theta = 0, phi = 0, dtheta = PI/20, dphi = PI/20; 
float r = 0.2; 

void setupmywindow() 
{ 
    glClearColor(1.0,1.0,1.0,0); 
    glColor3f(0.0, 0.0, 0.0); 
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glMatrixMode(GL_PROJECTION); 
    gluPerspective(30,1,2,100); 
    glMatrixMode(GL_MODELVIEW); 
    glEnable(GL_DEPTH_TEST); 
} 


void myaxes(double size) 
{ 
    glBegin(GL_LINES); 
     glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(1,0,0);glVertex3f(size,0,0); //x-axis 
     glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(0,1,0);glVertex3f(0,size,0); //y-axis 
     glColor3f(0,0,0);glVertex3f(0,0,0); glColor3f(0,0,1);glVertex3f(0,0,size); //z-axis 
    glEnd(); 
} 

void sphere() 
{ 
float z1, x1, y1, z2, x2, y2, z3, x3, y3, z4, x4, y4; 

float angle = 0,translate; 

glTranslatef(0.0,0.0,translate); 

angle++; 
glRotatef(angle, 1.0, 1.0, 1.0); 

glBegin(GL_QUAD_STRIP); 

for(theta=0;theta<=2.0*PI;theta+=dtheta) 
{ 
     for(phi=0;phi<=PI;phi+=dphi) 
      { 

      z1 = r * sin(phi + dphi) * cos(theta + dtheta); 
      x1 = r * sin(phi + dphi) * sin(theta + dtheta); 
      y1 = r * cos(phi + dphi); 

      z2 = r * sin(phi) * cos(theta + dtheta); 
      x2 = r * sin(phi) * sin(theta + dtheta); 
      y2 = r * cos(phi); 

      z3 = r * sin(phi) * cos(theta); 
      x3 = r * sin(phi) * sin(theta); 
      y3 = r * cos(phi); 

      z4 = r * sin(phi + dphi) * cos(theta); 
      x4 = r * sin(phi + dphi) * sin(theta); 
      y4 = r * cos(phi + dphi); 


glColor3f(1,0,0); 
glVertex3f(x4, y4, z4); 
glVertex3f(x1, y1, z1); 
glVertex3f(x2, y2, z2); 
glVertex3f(x3, y3, z3); 

      } 
} 
glEnd(); 

} 

void myDrawing() 
{ 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(r,theta,phi,0,0,0,0,1,0); 

    sphere(); 
    myaxes(1.5); 
    glutSwapBuffers(); 
} 

void mykeyboardcontrol(unsigned char key, int x, int y) 
{ 
    switch(key){ 
     case 'r': r+=0.1;break; //increase radius 
     case 'p': r-=0.1;break; //decrease radius 
     case 'u': theta+=PI/20;break;//increase theta angle 
     case 'f': phi+=PI/20;break;//increase phi angle 

    } 
    printf("r=%f theta=%f phi=%f\n",r,theta,phi); 
    if(key==27) exit(0); 

    if(theta>2*PI) theta-=2*PI; 
    if(phi>PI) phi-=PI; 

    printf("r=%f theta=%f phi=%f\n",r,theta,phi); 

    glutPostRedisplay(); 
} 

int main(int argc, char **argv) 
{ 

glutInit(&argc, argv); 
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); 
glutCreateWindow("Sphere"); 
setupmywindow(); 
glutDisplayFunc(myDrawing); 
glutKeyboardFunc(mykeyboardcontrol); 

glutMainLoop(); 
    } 
+0

这可能不会解决它,但glLoadIdentity();应该来自两个glMatrixMode调用setupmywindow() – SuperMaximo93 2011-05-04 17:19:27

+0

它也是如此。它出现在开始,但当我按下一个键消失。 – George 2011-05-04 17:24:18

+0

它对所有的键还是其中的一部分都做同样的事情? – SuperMaximo93 2011-05-04 17:25:48

回答

1

在这里你去:

#include <GL/glut.h> 
#include <cmath> 
#include <cstdlib> 
#include <cstdio> 

const float PI = 3.14159f; 
float camera_theta = 2.042033; 
float camera_phi = 8.639376; 
float camera_r = 15; 

double aspect_ratio = 0; 
void reshape(int w, int h) 
{ 
    aspect_ratio = (double)w/(double)h; 
    glViewport(0, 0, w, h); 
} 

void setupmywindow() 
{ 
    glClearColor(1,1,1,0); 
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
} 

void myaxes(double size) 
{ 
    glBegin(GL_LINES); 
    glColor3f(0,0,0); 
    glVertex3f(0,0,0); 
    glColor3f(1,0,0); 
    glVertex3f(size,0,0); //x-axis 

    glColor3f(0,0,0); 
    glVertex3f(0,0,0); 
    glColor3f(0,1,0); 
    glVertex3f(0,size,0); //y-axis 

    glColor3f(0,0,0); 
    glVertex3f(0,0,0); 
    glColor3f(0,0,1); 
    glVertex3f(0,0,size); //z-axis 
    glEnd(); 
} 

void sphere(float radius) 
{ 
    float z1, x1, y1, z2, x2, y2, z3, x3, y3, z4, x4, y4; 

    float dtheta = PI/20; 
    float dphi = PI/20; 

    glBegin(GL_QUADS); 
    for(float theta = 0; theta<=2.0*PI; theta+=dtheta) 
    { 
     for(float phi = 0; phi<=PI; phi+=dphi) 
     { 
      z1 = radius * sin(phi + dphi) * cos(theta + dtheta); 
      x1 = radius * sin(phi + dphi) * sin(theta + dtheta); 
      y1 = radius * cos(phi + dphi); 

      z2 = radius * sin(phi) * cos(theta + dtheta); 
      x2 = radius * sin(phi) * sin(theta + dtheta); 
      y2 = radius * cos(phi); 

      z3 = radius * sin(phi) * cos(theta); 
      x3 = radius * sin(phi) * sin(theta); 
      y3 = radius * cos(phi); 

      z4 = radius * sin(phi + dphi) * cos(theta); 
      x4 = radius * sin(phi + dphi) * sin(theta); 
      y4 = radius * cos(phi + dphi); 

      glColor3f(1,0,0); 
      glVertex3f(x4, y4, z4); 
      glVertex3f(x1, y1, z1); 
      glVertex3f(x2, y2, z2); 
      glVertex3f(x3, y3, z3); 
     } 
    } 
    glEnd(); 
} 

void display(void) 
{ 
    glEnable(GL_DEPTH_TEST); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(45, aspect_ratio, 1, 100); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    // spherical coordinate camera transform, +Z is "up" 
    glTranslatef(0 ,0 , -camera_r); 
    glRotatef((camera_theta - PI) * (180.0f/PI), 1,0,0); 
    glRotatef(-camera_phi * (180.0f/PI), 0,0,1); 

    sphere(2); 
    myaxes(5); 
    glutSwapBuffers(); 
} 

void mykeyboardcontrol(unsigned char key, int x, int y) 
{ 
    switch(key){ 
     case 'r': camera_r+=0.1;break; //increase radius 
     case 'p': camera_r-=0.1;break; //decrease radius 

     case 'i': camera_theta+=PI/20;break;//increase theta angle 
     case 'k': camera_theta-=PI/20;break;//increase theta angle 
     case 'j': camera_phi-=PI/20;break;//increase phi angle 
     case 'l': camera_phi+=PI/20;break;//increase phi angle 
     } 
    printf("r=%f theta=%f phi=%f\n",camera_r,camera_theta,camera_phi); 
    if(key==27) exit(0); 

    // clamp theta 
    if(camera_theta < 0) camera_theta = 0; 
    if(camera_theta > PI) camera_theta = PI; 

    // wrap phi 
    if(camera_phi > 2*PI) camera_phi -= 2*PI; 
    if(camera_phi < 2*PI) camera_phi += 2*PI; 

    printf("r=%f theta=%f phi=%f\n",camera_r,camera_theta,camera_phi); 

    glutPostRedisplay(); 
} 

int main(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 

    glutInitWindowSize(400,400); 
    glutCreateWindow("Sphere"); 

    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutKeyboardFunc(mykeyboardcontrol); 

    setupmywindow(); 
    glutMainLoop(); 
    return 0; 
} 

我不知道为什么你试图通过rthetaphigluLookAt(),所以我取代了有固定斜上下的摄像头角度看在原点。你也似乎在sphere()中覆盖thetaphi,炸掉mykeyboardcontrol()正在尝试做的任何事情。我无法确定您是想绕相机绕原点旋转还是画出部分球体。

+0

@genpfault:它现在几乎可以工作!一切都很好,但是我有一个角度问题。当我按下“u”或“f”来增加角度theta和phi时,没有任何反应。 – George 2011-05-04 19:15:21

+0

@genpfault:我的目的是制作一个球体并放置一个以中心为焦点的相机。我想改变球面坐标r,theta,phi。 – George 2011-05-04 19:22:21

+0

@乔治:固定,我想。 – genpfault 2011-05-04 19:33:43