利用OpenGL添加AutoCAD中的平移与缩放功能
1、添加openGL库,同过在dialog中添加picture控件来悬挂openGL视窗,悬挂方式如下:
[cpp]viewplaincopy
BOOLCDemoSectionDlg::InitPic()//初始化openGL视窗
{
CWndwnd=GetDlgItem(IDC_RENDER);//IDC_RENDER为picture控件ID
hrenderDC=::GetDC(wnd->m_hWnd);//hrenderDC为类成员变量HDChrenderDC;//设备上下文
if(SetWindowPixelFormat(hrenderDC)==FALSE)
return0;
if(CreateViewGLContext(hrenderDC)==FALSE)
return0;
CRectrc;
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);
returnTRUE;
}
BOOLCDemoSectionDlg::CreateViewGLContext(HDChDC)//创建viewGLContext
{
hrenderRC=wglCreateContext(hDC);//hrenderRC为类成员变量HGLRChrenderRC;//渲染上下文
if(hrenderRC==NULL)
returnFALSE;
if(wglMakeCurrent(hDC,hrenderRC)==FALSE)
returnFALSE;
returnTRUE;
}
BOOLCDemoSectionDlg::SetWindowPixelFormat(HDChDC)//设定像素格式
{
PIXELFORMATDESCRIPTORpixelDesc;
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)//Choosedefault
{
PixelFormat=1;
if(DescribePixelFormat(hDC,PixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
{
returnFALSE;
}
}
if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
{
returnFALSE;
}
returnTRUE;
}
2、在视窗上画图,函数如下:
[cpp]viewplaincopy
voidCDemoSectionDlg::RenderScene(doublex,doubley)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glScalef(ScralSize,ScralSize,0.0);
xTimes=1.4;
yTimes=0.9;
xLength=2B01+2B02+2B03+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(x1.0f,y1.0f,0.0f);
glTranslatef(-xTimes/2,yTimes/2,0);
glColor3f(1.0f,1.0f,1.0f);//设置当前色为白色
glBegin(GL_LINE_LOOP);
glVertex2f(0.0xRange,0.0);
glVertex2f(0.0xRange,-H01yRange);
glVertex2f(B01xRange,-(H01+H02)yRange);
glVertex2f(B01xRange,-(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,-H01yRange);
glVertex2f((B01+B02+B03+B04+B03+B02+B01)xRange,0.0yRange);
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,-H31yRange);
glVertex2f((B01+B02+B21)xRange,-H31yRange);
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,-H31yRange);
glVertex2f((B01+B02+B03+B04+B21)xRange,-H31yRange);
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,"TimesNewRoman");
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+2B03+B04+B02/2-40),-BTxtDist);
DrawCNString("BO1",(B01+2B02+2B03+B04+B01/2-40),-BTxtDist);
intB21=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);
}
voidCDemoSectionDlg::DrawCNString(constcharstr,intx,inty)
{
glColor3f(0.0f,0.0f,1.0f);
intlen,i;
wchar_twstring;
HDChDC=wglGetCurrentDC();
GLuintlist=glGenLists(1);
glRasterPos2f(xxRange,yyRange);
//计算字符的个数
//如果是双字节字符的(比如中文字符),两个字节才算一个字符
//否则一个字节算一个字符
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 {
wglUseFontBitmapsW(hDC,wstring[i],1,list);
glCallList(list);
}
//回收所有临时资源
free(wstring);
glDeleteLists(list,1);
glColor3f(1.0f,1.0f,0.0f);
}
voidCDemoSectionDlg::SelectFont(intsize,intcharset,constcharface)
{
HFONThFont=CreateFontA(size,0,0,0,FW_MEDIUM,0,0,0,
charset,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,face);
HFONThOldFont=(HFONT)SelectObject(wglGetCurrentDC(),hFont);
DeleteObject(hOldFont);
}
voidCDemoSectionDlg::DrawLine(CPointnS,CPointnE,BOOLIsAt,BOOLIsArrow,BOOLWithBorder)
{//该函数可以通过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)xRanwww.shanxiwang.netge,(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.xxRange,nS.yyRange);
glVertex2f(nE.xxRange,nE.yyRange);
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、通过添加鼠标事件执行相应重绘:
[cpp]viewplaincopy
//需先做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);
voidCDemoSectionDlg::OnLButtonDown(UINTnFlags,CPointpoint)
{
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);
}
voidCDemoSectionDlg::OnLButtonUp(UINTnFlags,CPointpoint)
{
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);
}
voidCDemoSectionDlg::OnMouseMove(UINTnFlags,CPointpoint)
{
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);
}
BOOLCDemoSectionDlg::OnMouseWheel(UINTnFlags,shortzDelta,CPointpt)
{
CPointpoint=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);
}
}
returnCDialog::OnMouseWheel(nFlags,zDelta,pt);
}
4、每次重绘需执行绘图函数,函数如2;
|
|