一、安装GLUT工具包
1下载OpenGL需要的库文件 ,一般可以选择下载glut库(内含所有必须文件)
2解压后将得到的glut.lib和glut32.lib这两个静态函数库复制到文件目录的lib文件夹下
X:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\lib
3将glut.dll,glut32.dll这两个动态库文件放到 *** 作系统目录下面的C:\Windows\system32文件夹内行枝(32位系统)或C:\Windows\SysWOW64(64位系统)。
为了兼容性考虑,最好在这两个目录下都复制相应的文件。
4将解压得到的头文件glut.h复制到目录如下目录下:
X:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\GL
提示:如果在incluce目录下没有GL文件夹,则需要手动创建
二、VS2013中的配置
创建一档燃敏段简个空白的Win32控制台应用程序
在代码最前面添加包含目录
#include <GL/glut.h>
然后就可以编辑自己的OpenGL程序了
例如:复制如下代码到刚配置好的VS中
#include <GL/glut.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
static int year = 0,spin=0, day = 0
static GLint fogMode
const int n = 100
const GLfloat R = 1.0f
const GLfloat Pi = 3.1415926536f
void DrawCircle()
{
int i
glClear(GL_COLOR_BUFFER_BIT)
glBegin(GL_LINE_LOOP)
for (i = 0i <n++i)
{
glColor3f(1.0, 0.0, 0.0)
glVertex2f(R*cos(2 * Pi / n*i), R*sin(2 * Pi / n*i))
}
glEnd()
glFlush()
}
void init(void)
{
GLfloat position[] = { 0.5, 0.5, 3.0, 0.0 }
glEnable(GL_DEPTH_TEST) //防止遮挡
glLightfv(GL_LIGHT0, GL_POSITION, position)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
{
GLfloat mat[3] = { 0.1745, 0.01175, 0.01175 }
glMaterialfv(GL_FRONT, GL_AMBIENT, mat)
mat[0] = 0.61424mat[1] = 0.04136mat[2] = 0.04136
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat)
mat[0] = 0.727811mat[1] = 0.626959mat[2] = 0.626959
glMaterialfv(GL_FRONT, GL_SPECULAR, mat)
glMaterialf(GL_FRONT, GL_SHININESS, 0.6*128.0)
}
glEnable(GL_FOG)
{
GLfloat fogColor[4] = { 0.5, 0.5, 0.5, 1.0 }
fogMode = GL_EXP
glFogi(GL_FOG_MODE, fogMode)
glFogfv(GL_FOG_COLOR, fogColor)
glFogf(GL_FOG_DENSITY, 0.35)
glHint(GL_FOG_HINT, GL_DONT_CARE)
glFogf(GL_FOG_START, 1.0)
glFogf(GL_FOG_END, 5.0)
}
glClearColor(0.5, 0.9, 0.9, 1.0) /* fog color */
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glColor3f(0.0, 1.0, 1.0)
glPushMatrix()//记住自己的位置
glutSolidSphere(1.0, 20, 16) /* 画太阳半径、 20经度、16纬度*/
glRotatef(spin, 0.0, 1.0, 0.0) //自转,绕着一个向量以给定角度旋转(正的为逆时针)
glTranslatef(2.0, 1.0, 0.0)
glRotatef(spin, 1.0, 0.0, 0.0)//公转
glRectf(0.1,0.1,0.5,0.5)
glColor3f(0.0, 0.0, 1.0)
glutWireSphere(0.2, 8, 8) /* 画第一颗小行星 */
glColor3f(1.0, 0.0, 0.0)
glTranslatef(2.0, 1.0, 0.0)
glRotatef(2 * spin, 0.0, 1.0, 0.0)
glutSolidSphere(0.5, 16, 8)
glPopMatrix()//回到原来的位置
glutSwapBuffers()
}
void spinDisplay(void)
{
spin = spin + 2
if (spin >360)
spin = spin - 360
glutPostRedisplay()
}
void mouse(int button,int state,int x,int y )
{
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay)
break
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL)
break
default:
break
}
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 0.5, 20.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(0.0, 10.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'd':
day = (day + 10) % 360
glutPostRedisplay()
break
case 'D':
day = (day - 10) % 360
glutPostRedisplay()
break
case 'y':
year = (year + 5) % 360
glutPostRedisplay()
break
case 'Y':
year = (year - 5) % 360
glutPostRedisplay()
break
case 27:
exit(0)
break
default:
break
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(400, 400)
glutInitWindowPosition(100, 100)
glutCreateWindow("OpengGL 程序设计--杨超")
init()
//glutDisplayFunc(DrawCircle)
glutDisplayFunc(display)
glutReshapeFunc(reshape)
//glutKeyboardFunc(keyboard)
glutMouseFunc(mouse)
glutMainLoop()
return 0
}
5编译后能正确运行说明配置成功!
qt可以通过QGLWidget运行opengl。QGLWidget继承QWidget,能够直接在里面调用opengl的接口。这个在qt文档里有具体说
明,也有相关例子,所以不赘述了。但是无法在正式软件里面执行,为什么?因为正式软件是用QGraphicsScene这个场景类 *** 作和 *** 作一切
item,而用QGraphicsView将其显示出来,而每一个item都是QGraphicsItem的子类。QGLWidget并不是QGraphicsItem类,我曾经尝试用普通的QWidget类那样,通过proxy来加进QGraphicsItem,但是没有成功。或许有方法,但是没有找到。
于是我放弃了用QGLWidget来 *** 作opengl的打算,寻找直接在QGraphicsItem中 *** 作opengl的方法。通过查看文档和示例代码,找到了这个方法:
1 往qt工程文件里添加opengl以及对应的lib。
2
对QGraphicsView进行一个三维对话框的指定,代码如下:
QGLWidget *widget = new
QGLWidget(QGLFormat(QGL::SampleBuffers))
widget->makeCurrent()
QGraphicsView
view
view.setViewport(widget)
上述代码唤唯洞告诉了 QGraphicsView 类当前绘制的对象是支持opengl的。于是所有的场景中的item都将绘制到widget 上。
3
写一个QGraphicsItem的继承类,特别要重写paint函数。代码如下:
void XXX::paint(QPainter
*painter, const QStyleOptionGraphicsItem *option, QWidget
*widget)
{
painter->beginNativePainting()
glColor3f(0.5,1.0,0.2)
glBegin(GL_TRIANGLES)
glVertex3f(100.0,100.0,-100.0)
glVertex3f(150.0, 100.0,
-100.0)
glVertex3f(100.0, 150.0,
-100.0)
glEnd()
painter->endNativePainting()
}
上面这个函数主要是用opengl接口绘制了一个三角形。记住,在opengl绘制之前一定要执行painter->beginNativePainting()以及painter->endNativePainting()这两个语句。
QGraphicsScene、
QGraphicsView和QGraphicsItem的关系可以查阅相关文档,也不赘述了。
不过我按照这个方式画的三角形,怎么也在窗口上显示和枯不出来,找了半天才发现问题在这个函数上QGraphicsItem::boundingRect()。这个函数是
干什么用的呢?主要用来返回该item的初始化大小,这个大小不会轻易改变,后续的改变都可以通过矩山判阵来完成,但是初始大小是不变的。QGraphicsView通过这个矩形来判断当前item是不是需要重绘,如果在重绘区外,则不调用重绘函数了。同时碰撞检测之类,也可以用这个矩形来判断。原来,item本身的矩阵外包框不对,所以才导致了重回不出来,改过来就正确了。
上面说的很潦草,具体怎么改的步骤就不说了。要想正确的绘制,必须得弄清楚坐标系的关系,QGraphicsScene、QGraphicsView以及QGraphicsItem这三个坐标系到底是什么关系。我看了文档,也自己进行了测试,但是感觉文档和测试的结果有些出入。具体出入不说了。说一下自己得心的吧。
先说明:涉及到一切大小和长度,都是像素大小,至少我测试的结果是这样的。
在建立QGraphicsScene
对象的时候,有一个构造函数是矩形,这个矩形是什么含义呢?经过测试,发现这个矩形并没有指定d出窗口的位置,比如,我把矩形的左上角点指定为
-1000,-1000,显示的位置和1000,1000是一样的,而长度则正确指定了(当然,可能会有滚动条)。所以,这个矩形的左上角点并不是显示的
窗口的位置,而是它在逻辑上的左上角点。我们显示一切item,都是以这个逻辑上的坐标系为准来绘制的。比如,左上角点是-1000,-1000,而
item的位置在-500,-500,则这个-500,-500相当于在显示窗口的左上角往下各加500个像素的坐标的位置。
那么 QGraphicsItem的boundingRect是什么意思呢?返回的是什么大小?是以什么坐标系显示的大小?首先,这个大小肯定是以像素为单位的,其次,这个矩形的坐标是以QGraphicsScene的逻辑坐标为准的。当然这个大小是没有任何矩阵叠加的大小。有了矩阵叠加后,实际的矩形可能会发生变化。假如在boundingRect中指定矩形的左上角为100,100,那么最终体现的位置则是QGraphicsScene逻辑坐标100,100的位置,如果QGraphicsScene的左上角点已经指定为-1000,-1000,那么这个位置实际上就是离窗口左上角点1100,1100的位置(由于有滚动条,所以也不一定是这个长度。)
那么在QGraphicsItem的paint函数中进行了opengl绘制用的是什么坐标呢?其实用的也是QGraphicsScene
的逻辑坐标。如上面的例子,绘制的直角三角形直角顶点是0,0,那么显示的位置就是距离显示窗口左上角点1000,1000的位置。不过opengl的所
有绘制都是没有矩阵叠加的基础上,如果用矩阵叠加,则显示的位置肯定和指定的有区别了。比如,我用setPos强制指定一个位置,这个位置将和opengl绘图坐标相叠加,最后显示到窗口上。我推测setPos其实是改变了矩阵,是一个平移矩阵。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)