的大坑 没计划去搞Direct x,反倒是因为不停的触及物理运算被迫又开了cuda并行运算的大坑,过两个月又要去搞AI了,整个人就处于不停的填坑过程疲于奔命 ;
而到了OPEN GL就一直挂在嘴边 但是实际上一直没有打开正确的使用方式 最近要写三维物理计算的论文所以特地又回来整open GL 搞演示
虽说OPENGL比Matlab原生的图形生成要麻烦的多 但是对于自定过程 比如自己写数据结构来绘制三维图形来说 open GL可以说是完胜 。
那么
那么先来说配置吧 默认win 10+vs2015为开发环境
1,去这里下载文件集
2,在“我的电脑”中搜索“gl.h”,并找到其所在文件夹(应该是其安装目录下面的“VC\PlatformSDK\include\gl文件夹”)。
3,把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹(应该是其安装目录下面的“VC\lib”文件夹)。
4,把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)
我不知道要不要考虑64位的情况 所以 步骤四中的两种dll文件同样要放到64位引用目录中去
朴素的情况就是C:\Windows\SysWOW64
配置完成后最好重启
当重启之后 我们新建一个c++控制台工程 在头文件中输入include< gl/>
当gl斜杠输完之后 如果出现了补全 那就说明头文件配置成功
随即 我们输入一段代码测试一下编译能否正常运行
#include
#include
#include
#include
using namespace std;
void drawline(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_LINE_STIPPLE);//打开虚线模式glDisable(GL_LINE_STIPPLE)可关闭
glLineStipple(2, 0x0F0F);//void glLineStipple(GLint factor, GLushort pattern); pattern为虚线样式序列(16位二进制数)
glLineWidth(10.0f);//线宽度
glBegin(GL_LINES);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}
void print(void (*func)())
{
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//显示方式
glutInitWindowPosition(100, 100);// 窗口位置
glutInitWindowSize(400, 400);//窗口位置
glutCreateWindow("第一个OpenGL程序");
glutDisplayFunc(func);//绘图函数 调用真正的显示函数
glutMainLoop();//主循环
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);//初始化
print(drawline);
}
如果上面的代码执行成功 那么就说明配置成功一切正常
注意以上这段程序并不是最朴素的open GL程序
那么我们就开始讲解一段OPEN GL程序都有哪些要素吧
首先带参的main函数肯定是必须的但是你真的知道这个参数是什么意思么?
第一个参数argc是一个int型形参,表示有多少个参数将传递给主函数mian()。实际传递的参数都以C风格字符串(即字符串数组)的形式保存在第二个形参argv中。
argv[]数组至少包含一个元素,通常argv[0]存储的是当前程序的路径和名称,从argv[1]到argv[argc-1]存储的是其他的命令行参数字符串。
main函数不能被其它函数调用,因此不可能在程序内部取得实际值。而我们如果在命令行环境下就可以对带形参的main函数进行赋值传值。
有了带参的main函数接下来就是初始化工作 这是基本比较固定的形式
glutInit(&argc, argv);//初始化
而在 之后既是窗口控制定义部分
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//显示方式
glutInitWindowPosition(100, 100);// 窗口位置
glutInitWindowSize(400, 400);//窗口位置
glutCreateWindow("第一个OpenGL程序");//窗口名称
glutDisplayFunc(func);//绘图函数 调用真正的显示函数
以上都是为绘图做一些准备工作,而在真正的绘图过程中需要另外有一些代码来制定绘图的规则
比如下面的模板样式其中中间的部分就是你可以定义的部分。
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin( /* 在这里填上你所希望的绘图模式 */ );
/* 在这里使用glVertex*系列函数 */
/* 指定你所希望的顶点位置 */
glEnd();
glFlush();
}
那么我们开始依照点线面的过程来叙述绘图的基本知识
glVertex2d
glVertex2f
glVertex3f
glVertex3fv
这些是所有vertex系列的类型后面的数字表示参数个数
i表示32位整数(OpenGL中将这个类型定义为GLint和GLsizei),
f表示32位浮点数(OpenGL中将这个类型定义为GLfloat和GLclampf),
d表示64位浮点数(OpenGL中将这个类型定义为GLdouble和GLclampd)。
v表示传递的几个参数将使用指针的方式,见下面的例子。
以下有一个图来理解这些类型所指定的东西
通过指定以上的类型然后点被赋予了不同的意义
比如:
void myDisplay(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
for(i=0; i
glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
glEnd();
glFlush();
}
通过这种方式画一个圆
点的大小也是可以被修改得比如
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(5.0f);//设置点的大小
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.5f);
glEnd();
glFlush();
}
说完
来说
既然点的大小可以指定 那线的的宽度肯定也是可以指定的啦
void glLineWidth(GLfloat width);
通过此方法来设置线段的宽度
而虚线则通过
glEnable(GL_LINE_STIPPLE);
glDisable(GL_LINE_STIPPLE);
来实现打开和关闭而虚线的种类则是一个16位二进制数 下图为对应的画线模式
void glLineStipple(GLint factor, GLushort pattern);
这其中factor是1决定的是接下来画的是(第一个画的是实线)
0则画虚线
这在我们的初始的demo中就可以看到应用我就不贴代码啦
那最后一环
有人模仿我的面?
我们都应该会有认识到 三维环境中一个多边形有两个面 (虽然我们不会严格定义区分)但 在OPENGL中设定的面朝我们的是正面 背朝我们的是反面
因此有了两个类型来规定面的正反 即
GL_FRONT
GL_BACK
而对面的处理方式则有填充和轮廓两种 即
GL_LINE
GL_FILL
而以上的模式设定通过什么语句来完成呢
即
glPolygonMode(面类型,填充类型);
同时有了以上操作 但是我就想翻转朝向怎么办?
glFrontFace(GL_CCW); // 设置CCW方向为“正面”,CCW即CounterClockWise,逆时针
glFrontFace(GL_CW); // 设置CW方向为“正面”,CW即ClockWise,顺时针
还有一个非常有用的对三维分析非常有用的模式就是镂空多边形模式 他可以让你绘制出模型的渲染网格(Render Mesh)
glEnable(GL_POLYGON_STIPPLE);//打开镂空模式
glDisable(GL_POLYGON_STIPPLE);//关闭
下篇将会更新一个demo绘图器的代码 常用的OPENGL代码都会整合在其中
好啦 关于GL的博客会常更新
下次再见
有错欢迎指出