OpenGL的几何变换

1.实验目的:
  理解掌握一个OpenGL程序平移、旋转、缩放变换的方法。

2.实验内容:
  (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移、旋转、缩放变换的方法;
  (2)根据示范代码,尝试完成实验作业;

3.实验原理:
  (1)OpenGL下的几何变换
  在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义。

  平移矩阵构造函数为glTranslate

   #include <GL/glut.h>

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0
    glMatrixMode(GL_MODELVIEW);
}

void drawSquare(void) //绘制中心在原点,边长为2的正方形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    {
        glVertex2f(-1.0f,-1.0f);//左下点
        glVertex2f(1.0f,-1.0f);//右下点
        glVertex2f(1.0f, 1.0f);//右上点
        glVertex2f(-1.0f,1.0f);//左上点
    }
    glEnd();
}

void myDraw1(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形

    glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
    glColor3f(0.0, 1.0, 0.0);
    drawSquare(); //绘制边长为2绿色正方形

    glTranslatef(0.0,-3.0,0.0); //再向下移动3单位
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void myDraw2(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形

    glPushMatrix();
    {
        glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
        glColor3f(0.0, 1.0, 0.0);
        drawSquare(); //绘制边长为2绿色正方形
    }
    glPopMatrix();

    glTranslatef(2.0,0.0,0.0); //再向右移动2单位
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Translate函数示例");

    init();
    glutDisplayFunc(myDraw1);
    glutMainLoop();
}

注意理解:myDraw1()和myDraw2()生成的图形完全相同,为什么?

 (2)、Rotate示例

#include <GL/glut.h>

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0
    glMatrixMode(GL_MODELVIEW);
}

void drawSquare(void) //绘制中心在原点,边长为2的正方形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    {
        glVertex2f(-1.0f,-1.0f);//左下点
        glVertex2f(1.0f,-1.0f);//右下点
        glVertex2f(1.0f, 1.0f);//右上点
        glVertex2f(-1.0f,1.0f);//左上点
    }
    glEnd();
}

void myDraw1(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形

    glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
    glRotatef(30,0.0,0.0,1.0); //逆时针旋转30角度
    glColor3f(0.0, 1.0, 0.0);
    drawSquare(); //绘制边长为2绿色正方形

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glTranslatef(-2.0,-3.0,0.0); //向左移动2单位,向下移动3单位
    glRotatef(-30,0.0,0.0,1.0); //顺时针旋转30角度
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void myDraw2(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形

    glPushMatrix(); //把当前矩阵压入堆栈
    {
        glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
        glRotatef(30,0.0,0.0,1.0); //逆时针旋转30角度
        glColor3f(0.0, 1.0, 0.0);
        drawSquare(); //绘制边长为2绿色正方形
    }
    glPopMatrix(); //从堆栈栈顶弹出一个矩阵为当前矩阵

    glTranslatef(-2.0,-3.0,0.0); //向左移动2单位,向下移动3单位
    glRotatef(-30,0.0,0.0,1.0); //顺时针旋转30角度
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Rotate函数示例");

    init();
    glutDisplayFunc(myDraw1);
    glutMainLoop();
}

(3)拉伸 glScalef

#include <GL/glut.h>
void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0
    glMatrixMode(GL_MODELVIEW);
}

void drawSquare(void) //绘制中心在原点,边长为2的正方形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    {
        glVertex2f(-1.0f,-1.0f);//左下点
        glVertex2f(1.0f,-1.0f);//右下点
        glVertex2f(1.0f, 1.0f);//右上点
        glVertex2f(-1.0f,1.0f);//左上点
    }
    glEnd();
}

void myDraw1(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形

    glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
    glScalef(1.0,1.5,1.0); //X和Z方向保持不变,Y方向放大为原来的1.5倍
    glColor3f(0.0, 1.0, 0.0);
    drawSquare(); //绘制边长为2绿色正方形

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glTranslatef(-2.0,-3.0,0.0); //向左移动2单位,向下移动3单位
    glScalef(0.5,1.5,1.0); //Z方向保持不变,X方向缩小为原来的0.5倍,Y方向放大为原来的1.5倍
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void myDraw2(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glColor3f(1.0, 0.0, 0.0);
    drawSquare(); //在原点处绘制边长为2红色正方形
    glPushMatrix(); //把当前矩阵压入堆栈
    {
        glTranslatef(2.0,3.0,0.0); //向右移动2单位,向上移动3单位
        glScalef(1.0,1.5,1.0); //X和Z方向保持不变,Y方向放大为原来的1.5倍
        glColor3f(0.0, 1.0, 0.0);
        drawSquare(); //绘制边长为2绿色正方形
    }
    glPopMatrix(); //从堆栈栈顶弹出一个矩阵为当前矩阵

    glTranslatef(-2.0,-3.0,0.0); //向左移动2单位,向下移动3单位
    glScalef(0.5,1.5,1.0); //Z方向保持不变,X方向缩小为原来的0.5倍,Y方向放大为原来的1.5倍
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //绘制边长为2蓝色正方形

    glFlush();
}

void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Scale函数示例");

    init();
    glutDisplayFunc(myDraw1);
    glutMainLoop();
}

(4)、综合示例

#include <GL/glut.h>

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0
    glMatrixMode(GL_MODELVIEW);
}

void drawSquare(void) //绘制中心在原点,边长为2的正方形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    {
        glVertex2f(-1.0f,-1.0f);//左下点
        glVertex2f(1.0f,-1.0f);//右下点
        glVertex2f(1.0f, 1.0f);//右上点
        glVertex2f(-1.0f,1.0f);//左上点
    }
    glEnd();
}

void myDraw(void)
{
    glClear(GL_COLOR_BUFFER_BIT); //清空

    glLoadIdentity(); //将当前矩阵设为单位矩阵
    glPushMatrix();
    {
        glTranslatef(0.0f,2.0f,0.0f);
        glScalef(3.0,0.5,1.0);
        glColor3f(1.0, 0.0, 0.0);
        drawSquare(); //上面红色矩形
    }
    glPopMatrix();

    glPushMatrix();
    {
        glTranslatef(-3.0,0.0,0.0);

        glPushMatrix();
        {
            glRotatef(45.0,0.0,0.0,1.0);
            glColor3f(0.0, 1.0, 0.0);
            drawSquare(); //中间左菱形
        }
        glPopMatrix();

        glTranslatef(3.0,0.0,0.0);

        glPushMatrix();
        {
            glRotatef(45.0,0.0,0.0,1.0);
            glColor3f(0.0, 0.7, 0.0);
            drawSquare(); //中间中菱形
        }
        glPopMatrix();

        glTranslatef(3.0,0.0,0.0);

        glPushMatrix();
        {
            glRotatef(45.0,0.0,0.0,1.0);
            glColor3f(0.0, 0.4, 0.0);
            drawSquare(); //中间右菱形
        }
        glPopMatrix();
    }
    glPopMatrix();

    glTranslatef(0.0,-3.0,0.0);
    glScalef(4.0,1.5,1.0);
    glColor3f(0.0, 0.0, 1.0);
    drawSquare(); //下面蓝色矩形

    glFlush();
}

void main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(600, 600);
    glutCreateWindow("几何变换函数综合示例");

    init();
    glutDisplayFunc(myDraw);
    glutMainLoop();
}

5.实验作业:

  绘制如下图形:
  这里写图片描述
提示:

  (1)写一个绘制菱形的函数drawDiamond(void); 

void drawDiamond(void) //绘制中心在原点的菱形
{
    glBegin(GL_POLYGON); //顶点指定需要按逆时针方向
    {
        glVertex2f(0.0f,-1.0f);//下点
        glVertex2f(2.0f,0.0f);//右点
        glVertex2f(0.0f, 1.0f);//上点
        glVertex2f(-2.0f,0.0f);//左点
    }
    glEnd();
}

 (2)用几何变换绘制三个不同位置、旋转角度、颜色的菱形。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值