openGL基本操作学习

要交关于openGL的作业了,所以就在网上找了一些教程,发现非常麻烦,就找了一本书看一看,顺便记录一些基本操作。

void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);创建正投影裁剪区域。
在使用glOrtho之前,需要先对坐标系进行设置,将其调整为投影坐标系

glMatrixMode(GL_PROJECTED);
glLoadIdentity();

绘制正方形,并且在改变窗口大小时,维持形状不变

//first one
#include <GL\glut.h>
#include <GL\GL.h>
#include <iostream>

void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0f, 0.0f, 0.0f);
    glRectf(-25.0f, 25.0f, 25.0f, -25.0f);

    glFlush();
}

void setUpRC(void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

void ChangeSize(GLsizei w, GLsizei h)
{
    GLfloat aspectRatio;
    if (h == 0)h = 1;

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);//重置坐标系统
    glLoadIdentity();

    aspectRatio = (GLfloat)w / (GLfloat)h;
    if (w <= h) 
        glOrtho(-100.0, 100.0, 
        -100.0 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
        //重新定义裁剪的区域,保持纵横比不变
    else
        glOrtho( -100.0 * aspectRatio, 100.0 * aspectRatio,
            -100.0, 100.0, 1.0, -1.0);
    std::cout << "w = " << w << "\th = " << h << std::endl;
    glMatrixMode(GL_MODELVIEW); //以后的变换都将影响这个模型
    glLoadIdentity();

}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutCreateWindow("Simple");
    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize);

    setUpRC();
    glutMainLoop();

    return 0;
}

生成动画:小方块在窗口内跑来跑去,碰到边界返回

//first one
#include <GL\glut.h>
#include <GL\GL.h>
#include <iostream>

GLfloat x1 = 0.0f;
GLfloat y = 0.0f;
GLfloat rsize = 25;

GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
GLfloat windowWidth, windowHeight;


void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    //定义颜色啊
    glColor3f(1.0f, 0.0f, 0.0f);
    glRectf(x1, y, x1 + rsize, y - rsize);

    //刷新绘图命令并进行交换
    glutSwapBuffers();
    /*glFlush();*/
}


void TimerFunction(int value)
{
    //到左边或右边时反转方向
    if (x1 > windowWidth - rsize || x1 < -windowWidth)xstep = -xstep;
    if (y > windowHeight || y < -windowHeight + rsize)ystep = -ystep;

    x1 = x1 + xstep;
    y = y + ystep;
    std::cout << "x,y: " << x1 << "," << y << std::endl;

    //检查边界,防止方块反弹时窗口变小,从而出现在新的裁剪区域外
    if (x1 > (windowWidth - rsize + xstep))x1 = windowWidth - rsize - 1;
    else if (x1 < -(windowWidth + xstep))x1 = -windowWidth - 1;

    if (y > (windowHeight + ystep))y = windowHeight - 1;
    else if (y < -(windowHeight - rsize + ystep))y = -windowHeight + rsize - 1;

    //std::cout << windowHeight << std::endl;
    //用新的坐标重新绘制场景
    glutPostRedisplay();
    glutTimerFunc(33, TimerFunction, 1);

}



void setUpRC(void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

void ChangeSize(GLsizei w, GLsizei h)
{
    glViewport(0, 0, w, h);
    windowHeight = (GLfloat)h/2;
    windowWidth = (GLfloat)w/2;

    glMatrixMode(GL_PROJECTION);//重置坐标系统
    glLoadIdentity();

    if (w <= h)
        glOrtho(-windowWidth, windowWidth,
            -windowHeight, windowHeight, 1.0, -1.0);
    else
        glOrtho( -windowWidth, windowWidth,
            -windowHeight, windowHeight, 1.0, -1.0);

    glMatrixMode(GL_MODELVIEW); //以后的变换都将影响这个模型
    glLoadIdentity();

}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    //支持双缓冲窗口
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Simple");
    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize);
    //glutTimeFunc: 经过33ms,就调用一下函数操作?
    glutTimerFunc(33, TimerFunction, 1);

    setUpRC();
    glutMainLoop();

    return 0;
}

到了这里,作业基本上就能搞定了,基本的openGL操作应该也差不多行了。

后面的内容有机会再看吧。有空再来更新
几何变换:管线
函数功能:
gluLookAt:在场景中建立观察者的位置??
使用照相机在场景中移动?
glTranslate/glRotate:在场景中设置物体的位置
glScale:对物体进行伸缩
gluPerspective:建立透视变换
glLoadMatrix/glMutMatrix:执行自己的矩阵变换

变换各种:
viewing:指定观察者和照相机的位置
modeling:在场景中移动物体
modelview:描述始图和模型变换的对偶性
projection:改变可视区域的大小或重新设置形状
viewport:伪变换,对窗口上的最终输出进行缩放

视图变换:确定场景的拍摄点,在进行其他变换之前需要先指定视图变换(在场景中放置照相机并让它指向某个方向)
投影变换:模型视图变换之后应用在物体的顶点之上,定义了可视区域,建立了裁剪平面(用它来确定几何图形能否被观察者看到)
投影方式:正投影 和 透视投影

在使用openGL提供的变换函数时,要注意的是,变换函数的效果是累积性的
解决方法:把模型视图矩阵重置为一个已知的状态
把单位矩阵加载到模型视图矩阵

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

矩阵堆栈:用于保存模型始图矩阵或者投影矩阵(保存自己经常使用的,方便操作)

照相机管理
照相机变换:

void gluLookAt(
GLdouble eyex, GLdouble eyey, GLdouble eyez, 
GLdouble centerx, GLdouble centery, GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz
);

实例:透视投影下太阳系的观察

#include <GL\glut.h>
#include <GL\GL.h>
#include <iostream>

void setUpRC()
{
    //一行代码实现消隐功能,强
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glColor3f(0.0f, 1.0f, 0.0f);
}

void TimerFunction(int value)
{
    //用新的坐标重新绘制场景
    glutPostRedisplay();
    glutTimerFunc(33, TimerFunction, 1);

}

void ChangeSize(GLsizei w, GLsizei h)
{
    GLfloat fAspect;
    if (h == 0)h = 1;

    //把视口设置为窗口大小
    glViewport(0, 0, w, h);

    //计算窗口的纵横比
    fAspect = (GLfloat)w / (GLfloat)h;

    //设置透视坐标系统
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //45°视野,近平面和远平面
    gluPerspective(45.0f, fAspect, 1.0, 425.0);

    //重置模型视图矩阵
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void RenderScene(void)
{
    //设置地球和月球之间的角度
    static float fMoonRot = 0.0f;
    static float fEarthRot = 0.0f;

    //用当前颜色清除窗口
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //保存矩阵状态并进行旋转
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    //把整个场景移动到视图中
    glTranslatef(0.0f, 0.0f, -300.0f);

    //设置材料颜色,太阳为黄色
    glColor3ub(255, 255, 0);
    glDisable(GL_LIGHTING);
    glutSolidSphere(15.0f, 15, 15);

    //旋转坐标系统
    glRotatef(fEarthRot, 0.0f, 1.0f, 0.0f);

    //绘制地球
    glColor3ub(0, 0, 255);
    glTranslatef(105.0f, 0.0f, 0.0f);
    glutSolidSphere(15.0f, 15, 15);

    //根据地球的坐标进行旋转,并绘制月球
    glColor3ub(200, 200, 200);
    glRotatef(fMoonRot, 0.0f, 1.0f, 0.0f);
    glTranslatef(30.0f, 0.0f, 0.0f);
    fMoonRot += 15.0f;
    if (fMoonRot > 360.0f)fMoonRot = 0.0f;
    glutSolidSphere(6.0f, 15, 15);

    //恢复矩阵状态
    glPopMatrix();//模型视图矩阵

    fEarthRot += 5.0f;
    if (fEarthRot > 360.0f)fEarthRot = 0.0f;

    //显示图像
    glutSwapBuffers();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    支持双缓冲窗口
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    //glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Simple");
    glutDisplayFunc(RenderScene);
    glutReshapeFunc(ChangeSize);
    glutTimerFunc(1000, TimerFunction, 1);

    setUpRC();
    glutMainLoop();

    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值