||
串口示波器毕竟只能显示波形,如果传输角度则显得不那么直观,利用OpenGL可以很直观的显示,例程参考了Nehe OpenG的相关代码。
用VC6.0新建一个MFC对话框程序名字为lb_OpenGL,基于对话框来建一个简单的OpenGL工程。
VC++ 6.0 环境下的opengl配置
首先OpenGLVC6.0版,将得到5个文件,以我的安装目录为例:
(1)“d:\Program Files\Microsoft Visual Studio\VC98\include\GL文件夹”。把解压得到的glut.h放到这个GL文件夹里。没有GL文件夹可以自己建一个,一般都有的。
(2)“d:\Program Files\Microsoft Visual Studio\VC98\lib文件夹”。把解压得到的glut.lib和glut32.lib放到静态函数库所在文件夹,即lib文件夹。
(3)把解压得到的glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。(典型的位置为:C:\Windows\System32)这是非常重要的动态链接库设置!
VS2010配置方法:首先下载附件中的OpenGL完整版库,解压缩后,把include里面的文件copy到D:\Program
Files\Microsoft Visual Studio 10.0\VC\include文件夹中,,然后把OpenGL库的lib文件夹中的文件全部copy到 D:\Program
Files\Microsoft Visual Studio 10.0\VC\lib中,最后,把OpenGL库里的bin文件夹中所有文件copy到C:\Windows\System32中
在项目工作区的FileView中找到StdAfx.h,添加下面的代码:
#include <GL/glu.h>
#include <GL/glaux.h>
在界面上拖入一个picture控件,改ID为IDC_RENDER。
在lb_OpenGLDlg.h中添加如下变量:
HGLRC hrenderRC; //RC
float m_yRotate; //转动角度
在lb_OpenGLDlg类中添加如下图中函数:
代码如下:
BOOL
CFangzhaoDlg_OpenGLDlg::CreateViewGLContext(HDC hDC)
{
hrenderRC =
wglCreateContext(hDC);
if(hrenderRC==NULL)
return FALSE;
if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
return FALSE;
return TRUE;
}
添加如图函数:
代码如下:
BOOL
CLb_OpenGLDlg::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR
pixelDesc;
pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;
pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER |
PFD_TYPE_RGBA;
pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 0;
pixelDesc.cRedShift = 0;
pixelDesc.cGreenBits = 0;
pixelDesc.cGreenShift = 0;
pixelDesc.cBlueBits = 0;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 0;
pixelDesc.cAccumRedBits = 0;
pixelDesc.cAccumGreenBits = 0;
pixelDesc.cAccumBlueBits = 0;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 0;
pixelDesc.cStencilBits = 1;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;
int PixelFormat =
ChoosePixelFormat(hDC,&pixelDesc);
if(PixelFormat==0) // Choose default
{
PixelFormat = 1;
if(DescribePixelFormat(hDC,PixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
{
return FALSE;
}
}
if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
{
return FALSE;
}
return TRUE;
}
添加如图函数:
函数如下:
void CLb_OpenGLDlg::RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 3.0, 6.0, /* eye is at (0,3,6) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in postivie Y direction */
// glTranslatef(0.0f,0.0f,0.0f); //
glRotatef(m_yRotate,0.0f,1.0f,0.0f); // 在XYZ轴上旋转立方体
glEnable(GL_BLEND); //使能半透明
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//半透明参数设置
glBegin(GL_QUADS); // 开始绘制立方体
glColor4f(0.0f,0.0f,1.0f,0.5f); // 颜色改为
glVertex3f( 1.0f,
1.0f,-1.0f); // 四边形的右上顶点 (顶面)
glVertex3f(-1.0f,
1.0f,-1.0f); // 四边形的左上顶点 (顶面)
glVertex3f(-1.0f, 1.0f,
1.0f); // 四边形的左下顶点 (顶面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor4f(0.0f,1.0f,0.0f,0.5f); // 颜色改成
glVertex3f( 1.0f,-1.0f,
1.0f); // 四边形的右上顶点(底面)
glVertex3f(-1.0f,-1.0f,
1.0f); // 四边形的左上顶点(底面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
glColor4f(0.0f,1.0f,1.0f,0.5f); // 颜色改成
glVertex3f( 1.0f, 1.0f,
1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f,
1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f,-1.0f,
1.0f); // 四边形的左下顶点(前面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor4f(1.0f,0.0f,0.0f,0.5f); // 颜色改成
glVertex3f(
1.0f,-1.0f,-1.0f); //
四边形的右上顶点(后面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
glVertex3f(-1.0f,
1.0f,-1.0f); // 四边形的左下顶点(后面)
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
glColor4f(1.0f,0.0f,1.0f,0.5f); // 颜色改成
glVertex3f(-1.0f, 1.0f,
1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f,
1.0f,-1.0f); // 四边形的左上顶点(左面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor4f(1.0f,1.0f,0.0f,0.5f); // 颜色改成
glVertex3f( 1.0f,
1.0f,-1.0f); // 四边形的右上顶点(右面)
glVertex3f( 1.0f, 1.0f,
1.0f); // 四边形的左上顶点(右面)
glVertex3f( 1.0f,-1.0f,
1.0f); // 四边形的左下顶点(右面)
glVertex3f(
1.0f,-1.0f,-1.0f); //
四边形的右下顶点(右面)
glEnd(); //
立方体绘制结束
SwapBuffers(hrenderDC);
}
若是不需要半透明则用下面的代码:
void CLb_OpenGLDlg::RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 3.0, 6.0,
/* eye is at (0,3,6) */
0.0, 0.0, 0.0, /* center is at (0,0,0) */
0.0, 1.0, 0.); /* up is in postivie Y direction */
// glTranslatef(0.0f,0.0f,0.0f); //
glRotatef(m_yRotate,0.0f,1.0f,0.0f); // 在XYZ轴上旋转立方体
glBegin(GL_QUADS); //
开始绘制立方体
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)
glEnd(); //
立方体绘制结束
SwapBuffers(hrenderDC);
}
添加事件函数如图:
代码如下:
void CFangzhaoDlg_OpenGLDlg::OnTimer(UINT
nIDEvent)
{
m_yRotate
+=3;
CDialog::OnTimer(nIDEvent);
}
在初始化函数OnInitDialog()中添加如下代码:
CWnd *wnd=GetDlgItem(IDC_RENDER);
hrenderDC=::GetDC(wnd->m_hWnd);
// hrenderDC = ::GetDC(this->GetSafeHwnd());//这句话是让全屏为背景的
if(SetWindowPixelFormat(hrenderDC)==FALSE)
return 0;
if(CreateViewGLContext(hrenderDC)==FALSE)
return 0;
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_FILL);
CRect rect; //在这个矩形中画图
GetDlgItem(IDC_RENDER)->GetWindowRect(&rect);
glViewport(0 , 0 , rect.Width() , rect.Height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f , rect.Width()/rect.Height() , 0.1f ,
100.0f);// 计算窗口的外观比例*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f);
// Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正
SetTimer(1,10,0);
差点忘了在构造函数中需要对m_yRotate初始化如下图:不然不会转动的。
代码为:m_yRotate=0;
运行程序将会出现一个俯视自转且半透明的正方体。如下图所示:
这个可以制作一个显示物体角度状体的上位机了,glRotatef(Angle,Xvector,Yvector,Zvector)负责让对象绕某个轴旋转。这个命令有很多用处。 Angle 通常是个变量代表对象转过的角度。 Xvector , Yvector 和 Zvector 三个参数则共同决定旋转轴的方向。比如(1,0,0)所描述的矢量经过X坐标轴的1个单位处并且方向向右。(-1,0,0)所描述的矢量经过X坐标轴的1个单位处,但方向向左。
通过这个函数可用来控制立方体的各个方向的旋转。gluLookAt这个函数用来确定视角。就不解释了。上面的例子如果不用定时器函数就不会有图像,调用RenderScene()即可,但是不能在OnInitDialog()中调用,通常是放在OnPaint()函数中。
OpenGL库VC6.0版下载地址:https://download.eeworld.com.cn/detail/lb8820265/558011
文中源代码下载地址:https://download.eeworld.com.cn/detail/lb8820265/558010