OpenGL 练习02 Sphere

哎呀,照着图形学课本上的部分代码画的一个球,用了一个晚上,一个下午的时间,中间还求助了他人,才把这个球画正确了。过程好艰辛,是用汗水与泪水画出来的球啊!

为什么那么难画?

1、我太粗心:抄式子的时候抄错了好几处地方

2、课本太粗心:有几处地方原本就是错的

不过还好,总算是画出来了,很开心!


#include<gl/glut.h>
#include<math.h>
//#include<gl/glu.h>
//#include<gl/gl.h>
 
// 1 radian = π / 180°
#define PI 3.14159
const float DegreeToRadians = PI / 180.0;
 
typedef GLfloat point3[3];
point3 quad_data[342];// 8 rows of 18 quads
 
point3 strip_data[40];
 
//全局变量
//窗口大小
int width = 600;
int height = 600;
 
//a point data type
typedef GLfloat point2[2];
 
//initial triangle
point2 v[] = {{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}};
 
void sphere_quad()// 计算球体的中间以四边形表示的部分的顶点坐标,并存入数组quad_data中,用GL_QUAD
{
    int k = 0;
    /*
    x(theta, phi) = sin theta cos phi
    y(theta, phi) = cos theta sin phi
    z(theta, phi) = sin phi
    */
    for (float phi = -80.0; phi < 80.0; phi += 20.0) //课本这里写成了phi <= 80.0,结果两极不一样!
    {
        float phir = phi * DegreeToRadians;
        float phir20 = (phi + 20) * DegreeToRadians;
        for (float theta = -180.0; theta <= 180.0; theta += 20.0)
        {
            float thetar = theta * DegreeToRadians;
            quad_data[k][0] = sin(thetar) * cos(phir);
            quad_data[k][1] = cos(thetar) * cos(phir);// 粗心大意 画出了一件艺术品来!是cos不是sin啊!
            quad_data[k][2] = sin(phir);
 
            glVertex3fv(quad_data[k]);
 
            k++;
 
            quad_data[k][0] = sin(thetar) * cos(phir20);//是thetar不是thetar20啊!
            quad_data[k][1] = cos(thetar) * cos(phir20);
            quad_data[k][2] = sin(phir20);
             
            glVertex3fv(quad_data[k]);
             
            k++;
        }
    }
}
 
void sphere_triangle() // 两极部分,用GL_TRIANGLE_FAN
{
    int k = 0;
    strip_data[k][0] = 0.0;
    strip_data[k][1] = 0.0;
    strip_data[k][2] = 1.0;
    glVertex3fv(strip_data[k]); // 这一点是那个三角形扇的顶点
    k++;
 
     
 
    float sin80 = sin(80.0 * DegreeToRadians);
    float cos80 = cos(80.0 * DegreeToRadians);
 
    for (float theta = -180.0; theta <= 180.0; theta += 20)
    {
        float thetar = theta * DegreeToRadians;     //
        strip_data[k][0] = sin(thetar) * cos80;
        strip_data[k][1] = cos(thetar) * cos80;
        strip_data[k][2] = sin80;
 
        glVertex3fv(strip_data[k]);
 
        k++;
    }
 
    glEnd();
 
    glBegin(GL_TRIANGLE_FAN);
 
    strip_data[k][0] = 0.0;
    strip_data[k][1] = 0.0;
    strip_data[k][2] = -1.0;
    glVertex3fv(strip_data[k]); // 这一点是那个三角形扇的顶点
    k++;
 
    for (float theta = -180.0; theta <= 180.0; theta += 20)
    {
        float thetar = theta * DegreeToRadians;                       //这里课本漏写了" * DegreeToRadians"
        strip_data[k][0] = sin(thetar) * cos80;
        strip_data[k][1] = cos(thetar) * cos80;
        strip_data[k][2] = -sin80;
 
        glVertex3fv(strip_data[k]);
 
        k++;
    }
}
 
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
 
    glViewport(0,0,(GLsizei)width,(GLsizei)height);
 
    glMatrixMode(GL_PROJECTION);//投影矩阵
        glLoadIdentity();
        gluPerspective(45, width/height, 1, 1000);
    glMatrixMode(GL_MODELVIEW);//模型矩阵
        glLoadIdentity();
        gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
 
        glRotatef(100, 1, 0, 0);//绕x轴旋转
 
    glEnable(GL_DEPTH_TEST);
 
    // 设置正反面为填充模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
    //glBegin(GL_TRIANGLE_STRIP);
    glBegin(GL_QUAD_STRIP);//把glBegin和glEnd放在显示回调函数中,而不是triangle函数中,绘制整个图形只需要调用一次glBegin和glEnd。
        glColor3f(0.0, 1.0, 1.0);
        sphere_quad();
    glEnd();
     
    glBegin(GL_TRIANGLE_FAN);
        //glColor3f(1.0, 0.0, 1.0);
        sphere_triangle();
    glEnd();
     
    glFlush();//交换两个缓冲区指针
}
 
void myinit()
{
    /*
    glMatrixMode(GL_PROJECTION);//投影矩阵
        glLoadIdentity();
        gluPerspective(45, width/height, 1, 1000);
 
    glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0, 0, 50, 0, 0, 0, 0, 1, 0);//设置摄像机参数(eye, at, up三个向量)
 
        glColor3f(0.0, 0.0, 0.0);
    */
    glClearColor(0.0, 0.0, 0.0, 1.0);
}
 
void myReshape(int w, int h)
{
    if (h == 0) h = 1;
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
 
    glMatrixMode(GL_PROJECTION);//投影矩阵
        glLoadIdentity();
        gluPerspective(45, width/height, 1, 1000);
}
 
 
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);//初始化GLUT
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);//设置图形显示模式。GLUT_DEPTH:使用深度缓存;GLUT_DOUBLE:使用双缓存;
    glutInitWindowPosition(100, 100);//设置窗口显示位置
    glutInitWindowSize(width,height);//设置窗口大小
    glutCreateWindow("Approximation of Sphere");//创建带标题的窗口
     
 
    myinit();
    glutDisplayFunc(display);//为当前窗口设置显示回调函数
    glutMainLoop();//进入GLUT事件处理循环
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值