配色: 字号:
利用OpenGL添加AutoCAD中的平移与缩放功能
2016-09-12 | 阅:  转:  |  分享 
  
利用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;



献花(0)
+1
(本文系网络学习天...首藏)