камера на сфере у opengl - проблема с поворотом и начальным окном - PullRequest
0 голосов
/ 04 мая 2011

Я хочу сделать сферу и поместить камеру, которая фокусируется в центре, имея вектор (VUP = 0,1,0). Я хочу изменить сферические координаты r, theta, phi.

Проблема в том, что когда я запускаю приложение, появляется сфера, но когда я нажимаю клавишу, она исчезает.Если я удаляю glMatrixMode (GL_PROJECTION) из окна настройки mywindow, то в начале сфера не появляется, но если я нажимаю клавишу, она появляется. Затем, нажимая «r» и «p», она меняет свой радиус, но нажимает«и» и «е» вращается только один шаг.

#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();
    }

1 Ответ

1 голос
/ 04 мая 2011

Вот, пожалуйста:

#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;
}

Понятия не имею, почему вы пытались передать r, theta и phi в gluLookAt(), поэтому я заменил это на фиксированныйугол наклона камеры, смотрящий на начало координат.Также вы, кажется, переписываете theta и phi в sphere(), уничтожая все, что mykeyboardcontrol() пытается сделать.Я не могу сказать, хотите ли вы вращать камеру вокруг источника или нарисовать частичную сферу.

...