要交关于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;
}