1、添加openGL库,同过在dialog中添加picture控件来悬挂openGL视窗,悬挂方式如下:
BOOL CDemoSectionDlg::InitPic()//初始化openGL视窗
{
CWnd *wnd = GetDlgItem(IDC_RENDER);//IDC_RENDER为picture控件ID
hrenderDC=::GetDC(wnd->m_hWnd); //hrenderDC为类成员变量HDC hrenderDC; //设备上下文
if(SetWindowPixelFormat(hrenderDC)==FALSE)
return 0;
if(CreateViewGLContext(hrenderDC)==FALSE)
return 0;
CRect rc;
wnd->GetClientRect(&rc);//rc为控件的大小。
glViewport(0, 0, (GLsizei)(rc.Width()), (GLsizei)(rc.Height()));
glMatrixMode(GL_PROJECTION);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
return TRUE;
}
BOOL CDemoSectionDlg::CreateViewGLContext(HDC hDC) //创建view GL Context
{
hrenderRC = wglCreateContext(hDC); //hrenderRC为类成员变量HGLRC hrenderRC; //渲染上下文
if(hrenderRC==NULL)
return FALSE;
if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
return FALSE;
return TRUE;
}
BOOL CDemoSectionDlg::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;
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;
}
2、在视窗上画图,函数如下:
void CDemoSectionDlg::RenderScene(double x,double y)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glScalef(ScralSize,ScralSize,0.0);
xTimes = 1.4;
yTimes = 0.9;
xLength = 2*B01+2*B02+2*B03+B04;//H01,H02,H03,B01,B02等需要通过edit控件获取,表示各部分尺寸
yLength = H01+H02+H03;
xRange = xTimes/xLength;//xLength通过相应尺寸计算出x向最大尺寸,xTimes为openGL绘图在x方向的放大倍数
yRange = yTimes/yLength;//yLength通过相应尺寸计算出y向最大尺寸,yTimes为openGL绘图在y方向的放大倍数
glTranslatef(x*1.0f,y*1.0f,0.0f);
glTranslatef(-xTimes/2,yTimes/2,0);
glColor3f(1.0f,1.0f,1.0f);//设置当前色为白色
glBegin(GL_LINE_LOOP);
glVertex2f(0.0*xRange,0.0);
glVertex2f(0.0*xRange,-H01*yRange);
glVertex2f(B01*xRange,-(H01+H02)*yRange);
glVertex2f(B01*xRange,-(H01+H02+H03)*yRange);
glVertex2f((B01+B02+B03+B04+B03+B02)*xRange,-(H01+H02+H03)*yRange);
glVertex2f((B01+B02+B03+B04+B03+B02)*xRange,-(H01+H02)*yRange);
glVertex2f((B01+B02+B03+B04+B03+B02+B01)*xRange,-H01*yRange);
glVertex2f((B01+B02+B03+B04+B03+B02+B01)*xRange,0.0*yRange);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f((B01+B02)*xRange,-(H31+H11)*yRange);
glVertex2f((B01+B02)*xRange,-(H01+H02+H03-H32-H12)*yRange);
glVertex2f((B01+B02+B11)*xRange,-(H01+H02+H03-H32)*yRange);
glVertex2f((B01+B02+B03-B12)*xRange,-(H01+H02+H03-H32)*yRange);
glVertex2f((B01+B02+B03)*xRange,-(H01+H02+H03-H32-H22)*yRange);
glVertex2f((B01+B02+B03)*xRange,-(H31+H21)*yRange);
glVertex2f((B01+B02+B03-B22)*xRange,-H31*yRange);
glVertex2f((B01+B02+B21)*xRange,-H31*yRange);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f((B01+B02+B03+B04)*xRange,-(H31+H11)*yRange);
glVertex2f((B01+B02+B03+B04)*xRange,-(H01+H02+H03-H32-H12)*yRange);
glVertex2f((B01+B02+B03+B04+B11)*xRange,-(H01+H02+H03-H32)*yRange);
glVertex2f((B01+B02+B03+B03+B04-B12)*xRange,-(H01+H02+H03-H32)*yRange);
glVertex2f((B01+B02+B03+B03+B04)*xRange,-(H01+H02+H03-H32-H22)*yRange);
glVertex2f((B01+B02+B03+B03+B04)*xRange,-(H31+H21)*yRange);
glVertex2f((B01+B02+B03+B03+B04-B22)*xRange,-H31*yRange);
glVertex2f((B01+B02+B03+B04+B21)*xRange,-H31*yRange);
glEnd();
/////////竖向左标注/////////
glColor3f(1.0f,1.0f,0.0f);//设置当前色为黄色
DrawLine(CPoint(-HLineDist,0),CPoint(-HLineDist,-H01),0,1,1);
DrawLine(CPoint(-HLineDist,-H01),CPoint(-HLineDist,-(H01+H02)),0,1,1);
DrawLine(CPoint(-HLineDist,-(H01+H02)),CPoint(-HLineDist,-(H01+H02+H03)),0,1,1);
/////////横向下标注/////////
DrawLine(CPoint(0,-(H01+H02+H03+BLineDist)),CPoint(B01,-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint(B01,-(H01+H02+H03+BLineDist)),CPoint((B01+B02),-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint((B01+B02),-(H01+H02+H03+BLineDist)),CPoint((B01+B02+B03),-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint((B01+B02+B03),-(H01+H02+H03+BLineDist)),CPoint((B01+B02+B03+B04),-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint((B01+B02+B03+B04),-(H01+H02+H03+BLineDist)),CPoint((B01+B02+B03+B04+B03),-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint((B01+B02+B03+B04+B03),-(H01+H02+H03+BLineDist)),CPoint((B01+B02+B03+B04+B03+B02),-(H01+H02+H03+BLineDist)),0,1,1);
DrawLine(CPoint((B01+B02+B03+B04+B03+B02),-(H01+H02+H03+BLineDist)),CPoint((B01+B02+B03+B04+B03+B02+B01),-(H01+H02+H03+BLineDist)),0,1,1);
//glRasterPos2f(0.5f, 0.0f);
SelectFont(15, GB2312_CHARSET, "Times New Roman");
DrawCNString("HO1",-HTxtDist,-(H01/2+7));
DrawCNString("HO2",-HTxtDist,-(H01+H02/2+7));
DrawCNString("HO3",-HTxtDist,-(H01+H02+H03/2+7));
DrawCNString("BO1",(B01/2-40),-BTxtDist);
DrawCNString("BO2",(B01+B02/2-40),-BTxtDist);
DrawCNString("BO3",(B01+B02+B03/2-40),-BTxtDist);
DrawCNString("BO4",(B01+B02+B03+B04/2-40),-BTxtDist);
DrawCNString("BO3",(B01+B02+B03+B04+B03/2-40),-BTxtDist);
DrawCNString("BO2",(B01+B02+2*B03+B04+B02/2-40),-BTxtDist);
DrawCNString("BO1",(B01+2*B02+2*B03+B04+B01/2-40),-BTxtDist);
int B21 = 60,H11=25;
DrawLine(CPoint(B01+B02+B03/2,0),CPoint(B01+B02+B03/2,-H11),0,1,1);
DrawCNString("H11",B01+B02+B21,-(H11/2+7));
SwapBuffers(hrenderDC);
}
void CDemoSectionDlg::DrawCNString(const char* str,int x,int y)
{
glColor3f(0.0f, 0.0f, 1.0f);
int len, i;
wchar_t* wstring;
HDC hDC = wglGetCurrentDC();
GLuint list = glGenLists(1);
glRasterPos2f(x*xRange,y*yRange);
// 计算字符的个数
// 如果是双字节字符的(比如中文字符),两个字节才算一个字符
// 否则一个字节算一个字符
len = 0;
for(i=0; str[i]!='\0'; ++i)
{
if( IsDBCSLeadByte(str[i]) )
++i;
++len;
}
// 将混合字符转化为宽字符
wstring = (wchar_t*)malloc((len+1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
wstring[len] = L'\0';
// 逐个输出字符
for(i=0; i<len; ++i)
{
wglUseFontBitmapsW(hDC, wstring[i], 1, list);
glCallList(list);
}
// 回收所有临时资源
free(wstring);
glDeleteLists(list, 1);
glColor3f(1.0f, 1.0f, 0.0f);
}
void CDemoSectionDlg::SelectFont(int size, int charset, const char* face)
{
HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,
charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);
DeleteObject(hOldFont);
}
void CDemoSectionDlg::DrawLine(CPoint nS,CPoint nE, BOOL IsAt,BOOL IsArrow,BOOL WithBorder)
{//该函数可以通过nS与nE定义带箭头标线的长度与位置来做标注,带有箭头,代码较多是因为添加了横向与竖向自动识别,
//IsAt标识暂时没用,表示相对当前激活点划线还是相对坐标原点划线。
//IsArrow标识是否带箭头
//WithBorder标识是否带边界线
if(IsAt)
{
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glEnd();
if(WithBorder&&nE.x==0)
{
glBegin(GL_LINES);
glVertex2f((nS.x-25)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+25)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x-25)*xRange,(nS.y+nE.y)*yRange);
glVertex2f((nS.x+nE.x+25)*xRange,(nS.y+nE.y)*yRange);
glEnd();
}
if(WithBorder&&nE.y==0)
{
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y-25)*yRange);
glVertex2f((nS.x)*xRange,(nS.y+25)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y-25)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y+25)*yRange);
glEnd();
}
if(IsArrow&&(nE.x==0))
{
//glVertex2f((nS.x)*xRange,(nS.y)*yRange);
if(nE.y<0)
{
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x-6)*xRange,(nS.y+nE.y+18)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glVertex2f((nS.x+nE.x+6)*xRange,(nS.y+nE.y+18)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-6)*xRange,(nS.y-18)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+6)*xRange,(nS.y-18)*yRange);
glEnd();
}
else
{
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x-6)*xRange,(nS.y+nE.y-18)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glVertex2f((nS.x+nE.x+6)*xRange,(nS.y+nE.y-18)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-6)*xRange,(nS.y+18)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+6)*xRange,(nS.y+18)*yRange);
glEnd();
}
}
if(IsArrow&&(nE.y==0))
{
//glVertex2f((nS.x)*xRange,(nS.y)*yRange);
if(nE.x<0)
{
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x+18)*xRange,(nS.y+nE.y+6)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glVertex2f((nS.x+nE.x+18)*xRange,(nS.y+nE.y-6)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-18)*xRange,(nS.y+6)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x-18)*xRange,(nS.y-6)*yRange);
glEnd();
}
else
{
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x-18)*xRange,(nS.y+nE.y+6)*yRange);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glVertex2f((nS.x+nE.x-18)*xRange,(nS.y+nE.y-6)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+18)*xRange,(nS.y+6)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+18)*xRange,(nS.y-6)*yRange);
glEnd();
}
}
}
else
{
//glVertex2f((nS.x)*xRange,(nS.y)*yRange);
//glVertex2f((nS.x+nE.x)*xRange,(nS.y+nE.y)*yRange);
glBegin(GL_LINES);
glVertex2f(nS.x*xRange,nS.y*yRange);
glVertex2f(nE.x*xRange,nE.y*yRange);
glEnd();
if(WithBorder&&(nE.x-nS.x==0))
{
glBegin(GL_LINES);
glVertex2f((nS.x-25)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+25)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x-25)*xRange,(nE.y)*yRange);
glVertex2f((nE.x+25)*xRange,(nE.y)*yRange);
glEnd();
}
if(WithBorder&&(nE.y-nS.y==0))
{
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y-25)*yRange);
glVertex2f((nS.x)*xRange,(nS.y+25)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x)*xRange,(nE.y-25)*yRange);
glVertex2f((nE.x)*xRange,(nE.y+25)*yRange);
glEnd();
}
if(IsArrow&&(nE.x-nS.x==0))
{
//glVertex2f((nS.x)*xRange,(nS.y)*yRange);
if(nE.y-nS.y<0)
{
glBegin(GL_LINES);
glVertex2f((nE.x-6)*xRange,(nE.y+18)*yRange);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glVertex2f((nE.x+6)*xRange,(nE.y+18)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-6)*xRange,(nS.y-18)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+6)*xRange,(nS.y-18)*yRange);
glEnd();
}
else
{
glBegin(GL_LINES);
glVertex2f((nE.x-6)*xRange,(nE.y-18)*yRange);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glVertex2f((nE.x+6)*xRange,(nE.y-18)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-6)*xRange,(nS.y+18)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+6)*xRange,(nS.y+18)*yRange);
glEnd();
}
}
if(IsArrow&&(nE.y-nS.y==0))
{
//glVertex2f((nS.x)*xRange,(nS.y)*yRange);
if(nE.x-nS.x<0)
{
glBegin(GL_LINES);
glVertex2f((nE.x+18)*xRange,(nE.y+6)*yRange);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glVertex2f((nE.x+18)*xRange,(nE.y-6)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x-18)*xRange,(nS.y+6)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x-18)*xRange,(nS.y-6)*yRange);
glEnd();
}
else
{
glBegin(GL_LINES);
glVertex2f((nE.x-18)*xRange,(nE.y+6)*yRange);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nE.x)*xRange,(nE.y)*yRange);
glVertex2f((nE.x-18)*xRange,(nE.y-6)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x+18)*xRange,(nS.y+6)*yRange);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glEnd();
glBegin(GL_LINES);
glVertex2f((nS.x)*xRange,(nS.y)*yRange);
glVertex2f((nS.x+18)*xRange,(nS.y-6)*yRange);
glEnd();
}
}
}
}
3、通过添加鼠标事件执行相应重绘:
//需先做OnInitDialog中的初始化
MouseLDStart = (0,0);
MouseLDEnd = (0,0);
LastPoint = (0,0);
MouseLDFlag=0;
CurX=0.0;
CurY=0.0;
LastX = 0.0;
LastY = 0.0;
ScralSize=1.0;
//GetDlgItem(IDC_RENDER)->GetWindowRect(&PicRect);
GetDlgItem(IDC_RENDER)->GetWindowRect(&rc);
PicRect=rc;
ScreenToClient(&rc);
void CDemoSectionDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
if((point.x>=rc.TopLeft().x)&&(point.x<=rc.BottomRight().x)&&
(point.y>=rc.TopLeft().y)&&(point.y<=rc.BottomRight().y))
{
MouseLDStart = point;
MouseLDFlag=TRUE;
}
CDialog::OnLButtonDown(nFlags, point);
}
void CDemoSectionDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
if(MouseLDFlag)
{
LastX=LastX+(point.x-MouseLDStart.x)/1.0/(PicRect.Width())*2.0/ScralSize;
LastY=LastY+(MouseLDStart.y-point.y)/1.0/(PicRect.Height())*2.0/ScralSize;
}
MouseLDFlag=FALSE;
CDialog::OnLButtonUp(nFlags, point);
}
void CDemoSectionDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if(MouseLDFlag==TRUE)
{
CurX=LastX+(point.x-MouseLDStart.x)/1.0/(PicRect.Width())*2.0/ScralSize;
CurY=LastY+(MouseLDStart.y-point.y)/1.0/(PicRect.Height())*2.0/ScralSize;
RenderScene(CurX,CurY);
}
CDialog::OnMouseMove(nFlags, point);
}
BOOL CDemoSectionDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
CPoint point = pt;
ScreenToClient(&point);
if((point.x>=rc.TopLeft().x)&&(point.x<=rc.BottomRight().x)&&
(point.y>=rc.TopLeft().y)&&(point.y<=rc.BottomRight().y))
{
if(zDelta>=0)
{
ScralSize=ScralSize+0.1;
RenderScene(CurX,CurY);
}
else
{
ScralSize=ScralSize-0.1;
RenderScene(CurX,CurY);
}
}
return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
4、每次重绘需执行绘图函数,函数如2;5、最终效果如下: