概述
Opengl
学习网站
想要系统的学,推荐learnopengl网站官网链接.,同时可以看工具书《OpenGL编程指南(第8版)》
目前市面上的教程,大部分是针对新版本的opengl,即核心渲染模式,核心渲染模式更灵活也更难,因项目需要,我目前只是紧急的学习了opengl1.0+版本的简单操作,以后有机会的话再学习3.3版本的。
入门理解
opengl是一个渲染工具库,我们能操作的只用两种,一种是设置函数,一种是使某个设置生效函数
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
如上述两个,一个设置了clear清除动作时候用什么颜色清除,第二行表示开始clear这个动作,清除的对象就是GL_COLOR_BUFFER_BIT,即颜色缓冲池
简单绘制
在1.0+版本中,绘制几何图形非常简单,通过glbegin开始,glend结束,中间写需要的数据点,通过不同的绘制模式,来绘制不同的几何形状:
glBegin(GLenum mode);
glVertex3d(x,y,z);
glEnd();
常用的绘制模式有:
GL_POINTS 画离散的点
GL_LINES 画线(每两个点连成一条线)
GL_LINE_STRIP 画线(所有点相互相连,首尾不相连)
GL_LINE_LOOP 画线(所有点相互相连,首尾相连)
GL_POLYGON 填充面(将所有点围成的面进行填充)
GL_QUADS 填充面(将每四个点围成的面进行填充,相邻点之间不填充)
GL_QUAD_STRIP 填充面(每两个点构成一条线,每两个线构成一个四边形)
GL_TRIANGLES 填充三角形(将每三个点围成的三角形进行填充,相邻的点之间不填充)
GL_TRIANGLE_STRIP 填充三角形(将每三个点围成的三角形进行填充,相邻的点之间填充)
GL_TRIANGLE_FAN 填充三角形(以第一个点为顶点,之后每两个点合起来围成的三角形进行填充,相邻的点之间填充)
理解世界坐标、窗口坐标
这一节建议仔细看learnopengl网站,坐标系统这一章节,教程链接: link.
个人理解:
所有的工作目的,都是为了将一个我们构建的3d世界,在2d的电脑屏幕上合理地显示出来。其中有三个主要的矩阵,通过改变这些矩阵,能做到控制展示的效果。
一般通过改变GL_MODELVIEW矩阵,来旋转、平移、缩放世界中的物体
一般通过改变GL_PROJECTION矩阵,来改变投影的效果
opengl会时刻维护这两个矩阵,提供的关于矩阵的操作函数,都是对于当前矩阵来说的,如果想用一个矩阵乘modelview矩阵,那么需要先把modelview矩阵切换到当前矩阵,再使用乘法操作。
为了更好的理解坐标的问题,以下是一些实际例子讲解
// 创建了两个vector,用来保存opengl的两个矩阵
std::vector<double> projectionmatrix;
std::vector<double> modelviewmatrix;
glMatrixMode(GL_MODELVIEW);
// 切换当前矩阵为GL_MODELVIEW矩阵
glLoadIdentity();
// 设置当前矩阵为单位阵,即物体没有变化
glTranslated(0,0,-2);
// 移动当前矩阵,沿z轴负向2单位,即站在0,0,0看,物体在0,0,-2
glGetDoublev(GL_MODELVIEW_MATRIX, &modelviewmatrix[0]);
// 获取当前的矩阵,并保存到自定义的modelviewmatrix
glMultMatrixd(&modelviewmatrix[0]);
// 乘法操作,这样操作会让modelviewmatrix矩阵与当前矩阵相乘
// 这一步操作没有实际意义,只是为了展示如何进行乘法操作
// 在我们需要时,可以将数据存到modelviewmatrix,再乘进当前矩阵
glMatrixMode(GL_PROJECTION);
// 切换当前矩阵为GL_PROJECTION矩阵
通过glVertex3d(x,y,z)这种方式设置的数据,opengl在获得了所有的数据之后,会按比例,把他们的坐标缩放到【-1,1】之间,初始时,所有数据构成的整体会在世界坐标(0,0,0)处,经过modelview矩阵,他们会被整体旋转平移,例如上例中,如果使用了glTranslated,他们就会被平移。
在经过裁剪、投影,最终会被呈现在我们的2d窗口上。具体投影、裁剪的过程,如果不设置不干预,opengl自己会做。
从鼠标窗口坐标到世界坐标转化
这是一个很常用的功能,展示一下标准代码 :
void SketcherInteractiveWindow::pick_point(int x, int y)
{
// 这是我在qt里的程序,x,y是qt窗口获取到鼠标事件的,鼠标的x,y窗口坐标
makeCurrent();
// 这个函数是“激活”了当前opengl状态机,因为多线程情况下,要保证正确,调用这个函数,就能保证你现在做的操作,操作的是当前的opengl状态机
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(&projectionmatrix[0]);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(&modelviewmatrix[0]);
// 把当前矩阵保存下来
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
// 获取你的视口大小,注意,视口和窗口可能一致,可能不一致,opengl最后呈现在视口,qt是窗口坐标
GLdouble winX = double(x);
GLdouble winY = double(height() - y);
// qt的xy方向和opengl xy方向不一致
winY = winY / height() * viewport[3];
// 这里是我的qt窗口和opengl视口大小不一样,我做了一个等比例修改
GLfloat winZ = 0.0;
glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
// glReadPixels,功能是读取当前winx,winy下,世界里,第一个深度值
// 怎么理解?当3d变成2d,会有深度的区别,这个函数能读取你鼠标指的那个位置的
// 最前面的那个像素,返回winz的值
double newx,newy,newz;
gluUnProject(winX, winY, (GLdouble)winZ, &modelviewmatrix[0], &projectionmatrix[0], viewport, &newx, &newy, &newz);
// 注意,这里winx、winy、winz都是上面的视口坐标
// modelviewmatrix、projectionmatrix都是我上个例子给出的,我自己保存的opegnl两个矩阵
// 整个函数的功能是,根据屏幕上面展示的坐标,倒退,找到世界坐标
}
视口、投影、裁剪
之后会把这节更新上,未完待续……
最后
以上就是大胆钻石为你收集整理的Opengl 入门,学习网站,常用函数详解 (gluproject,gluUnProject,glReadPixels)Opengl的全部内容,希望文章能够帮你解决Opengl 入门,学习网站,常用函数详解 (gluproject,gluUnProject,glReadPixels)Opengl所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复