第三章 图形对象.docx

上传人:b****8 文档编号:30461242 上传时间:2023-08-15 格式:DOCX 页数:29 大小:600.12KB
下载 相关 举报
第三章 图形对象.docx_第1页
第1页 / 共29页
第三章 图形对象.docx_第2页
第2页 / 共29页
第三章 图形对象.docx_第3页
第3页 / 共29页
第三章 图形对象.docx_第4页
第4页 / 共29页
第三章 图形对象.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

第三章 图形对象.docx

《第三章 图形对象.docx》由会员分享,可在线阅读,更多相关《第三章 图形对象.docx(29页珍藏版)》请在冰豆网上搜索。

第三章 图形对象.docx

第三章图形对象

第三章图形对象

即使人们不知道苹果和梨是怎么种植的,也可以吃掉它们。

那么能否不必知道构造细节,也可以绘制出复杂的图形呢?

可以,图形对象就干这种事情。

Intra3D的图形对象隐藏了几何造型与绘制的细节,用户使用简单的几个接口函数就可以绘制出图形。

Intra3D2.0版提供了三类图形对象:

(1)常用几何对象,如长方体、锥体、圆柱体、球体、圆环体、Swept形体等对象;

(2)多边形模型对象,用于绘制Autodesk公司.3ds模型和Wavefront公司的.obj模型;

(3)商业统计图形对象,如柱形图、带状图、条形图、折线图、面积图、饼图、塔形图、曲线图、曲面图、进程图、股票图等对象。

Intra3D将“图形对象”和“形体节点”(见第四章)分层设计。

图形对象负责绘制,形体节点则处理3D交互。

形体节点可以动态地引用图形对象,从而实现交互式绘制。

这种分层设计可使Intra3D核心库具有良好的可扩展性,并使交互式3D应用程序的开发更加灵活。

3.1图形对象的基类与COM接口

图形对象的基类为GraphicalObject,相应的COM接口为IGraphicalObject。

在C++类库中,几何图形对象如BoxObject、ConeObject、CylinderObject、SphereObject与TorusObject,多边形模型对象如Model3DS与ModelOBJ,商业统计图形对象如ColumnChart3D、RibbonChart3D、LineChart2D与BartChar2D等,均为GraphicalObject的派生类。

在COM库中,上述对象均继承接口IGraphicalObject。

C++类库中GraphicalObject是Container的派生类,应使用AddRef与Release函数来管理内存。

源程序见Intra3D-DLL\Include\Layer2\GraphicalObject.h。

其定义如下:

classGraphicalObject:

publicContainer

{

public:

virtualvoidDraw(void){}//图形绘制函数

//获取对象的包围盒,(dx,dy,dz)为长方体的幅值,(cx,cy,cz)为中心坐标,

virtualvoidGetBoundBox(float*dx,float*dy,float*dz,float*cx,float*cy,float*cz)

{*dx=*dy=*dz=0;*cx=*cy=*cz=0;}

//获取对象的包围球,(cx,cy,cz)为中心坐标,radius为半径

virtualvoidGetBoundSphere(float*radius,float*cx,float*cy,float*cz)

{*cx=*cy=*cz=0;*radius=0;}

//获取对象的最小坐标值(minx,miny,minz)与最大坐标值(maxx,maxy,maxz)

virtualvoidGetMinMax(float*minx,float*miny,float*minz,float*maxx,float*maxy,float*maxz)

{*minx=*miny=*minz=-0;*maxx=*maxy=*maxz=0;}

};

其中公有函数Draw、GetBoundBox、GetBoundSphere与GetMinMax均为虚函数,具体行为由派生类定义。

COM接口IGraphicalObject的定义如下(见Intra3D-COM\Intra3D.idl文件):

interfaceIGraphicalObject:

IDispatch

{

HRESULTDraw();

HRESULTGetMinMax([out]float*minX,[out]float*minY,[out]float*minZ,

[out]float*maxX,[out]float*maxY,[out]float*maxZ);

HRESULTGetBoundSphere([out]float*radius,[out]float*cx,[out]float*cy,[out]float*cz);

HRESULTGetBoundBox([out]float*dx,[out]float*dy,[out]float*dz,

[out]float*cx,[out]float*cy,[out]float*cz);

};

3.2常用几何图形对象

Intra3D2.0C++类库与COM库中的常用几何图形对象有BoxObject、ConeObject、CylinderObject、SphereObject与TorusObject。

由于这几种图形对象的设计非常相似,本节仅以SphereObject为例讲述程序设计。

程序的重点是AddRef、Release与FinalRelease的使用。

3.2.1类SphereObject的程序

C++类库中的SphereObject程序见Intra3D-DLL\Include\Layer2\SphereObject.h和Intra3D-DLL\Layer2\SphereObject.cpp。

类SphereObject的定义如下:

classSphereObject:

publicGraphicalObject

{

public:

SphereObject(void);//构造函数

voidSetSphere(floatradius,intslices=32);//设置球体参数

voidSetDrawMode(intmode);//设置绘制模式

voidSetMaterial(Material*pMat);//设置材质

voidSetTexture(Texture2D*pTex);//设置纹理

//-------------------以下为基类GraphicalObject的虚函数------------------

virtualvoidDraw(void);

virtualvoidGetMinMax(float*minX,float*minY,float*minZ,

float*maxX,float*maxY,float*maxZ);

virtualvoidGetBoundSphere(float*radius,float*cx,float*cy,float*cz);

virtualvoidGetBoundBox(float*dx,float*dy,float*dz,float*cx,float*cy,float*cz);

protected:

virtualvoidFinalRelease(void);//基类Container的虚函数

protected:

floatm_fRadius;//球体半径

intm_iSlices;//球体经纬等份数

intm_iDrawMode;//绘制模式,取SOLID或者WIRE

Material*m_pMaterial;//引用材质

Texture2D*m_pTexture;//引用纹理

};

构造函数用于初始化成员变量:

SphereObject:

:

SphereObject(void)

{

m_fRadius=1.0;

m_iSlices=32;

m_iDrawMode=SOLID;

m_pMaterial=NULL;

m_pTexture=NULL;

}

SetMaterial函数用于引用外部定义的材质对象:

voidSphereObject:

:

SetMaterial(Material*pMat)

{

//1

if(m_pMaterial!

=NULL)

m_pMaterial->Release();

//2

m_pMaterial=pMat;

//3

if(pMat!

=NULL)

m_pMaterial->AddRef();

}

SetTexture函数用于引用外部定义的纹理对象:

voidSphereObject:

:

SetTexture(Texture2D*pTex)

{

//1

if(m_pTexture!

=NULL)

m_pTexture->Release();

//2

m_pTexture=pTex;

//3

if(pTex!

=NULL)

m_pTexture->AddRef();

}

当SphereObject:

:

Release在删除自身时,应先消除对材质对象和纹理对象的引用。

此工作由SphereObject:

:

FinalRelease函数实现:

voidSphereObject:

:

FinalRelease(void)

{

if(m_pMaterial!

=NULL)

m_pMaterial->Release();

if(m_pTexture!

=NULL)

m_pTexture->Release();

}

SetSphere函数用于设置球体的参数。

SetDrawMode用于设置球体的绘制模式,绘制模式有两种,可取SOLID或WIRE模式。

voidSphereObject:

:

SetSphere(floatradius,intslices)

{

m_fRadius=radius;

m_iSlices=slices;

}

voidSphereObject:

:

SetDrawMode(intmode)

{

m_iDrawMode=mode;

}

Draw函数用于绘制球体。

当绘制模式为WIRE时,一般应将光照明关闭,否则由于光照明计算使得线框图时明时暗。

如果关闭光照明则导致材质不起作用,此时可将材质的Diffuse颜色作为线框图的颜色。

voidSphereObject:

:

Draw(void)

{

if(m_pMaterial!

=NULL)

{

//如果关闭光照明则材质不起作用,此时可将材质的Diffuse颜色作为当前颜色

floatcolor[3];

m_pMaterial->GetDiffuseColor(color);

glColor3fv(color);

m_pMaterial->Apply();

}

if(m_pTexture!

=NULL)

{

glEnable(GL_TEXTURE_2D);

m_pTexture->Apply();

}

if(m_iDrawMode==SOLID)

{

DrawSolidSphere(m_fRadius,m_iSlices);

}

elseif(m_iDrawMode==WIRE)

{

intflag;

glGetIntegerv(GL_LIGHTING,&flag);

if(flag)glDisable(GL_LIGHTING);

DrawWireSphere(m_fRadius,m_iSlices);

if(flag)glEnable(GL_LIGHTING);

}

if(m_pTexture!

=NULL)

glDisable(GL_TEXTURE_2D);

}

GetBoundBox、GetBoundSphere与GetMinMax函数的程序如下:

voidSphereObject:

:

GetBoundBox(float*dx,float*dy,float*dz,float*cx,float*cy,float*cz)

{

*cx=*cy=*cz=0;

*dx=*dy=*dz=m_fRadius*2.0f;

}

voidSphereObject:

:

GetBoundSphere(float*radius,float*cx,float*cy,float*cz)

{

*radius=m_fRadius;

*cx=*cy=*cz=0;

}

voidSphereObject:

:

GetMinMax(float*minx,float*miny,float*minz,

float*maxx,float*maxy,float*maxz)

{

*minx=*miny=*minz=-m_fRadius;

*maxx=*maxy=*maxz=m_fRadius;

}

3.2.2COM对象SphereObject的程序

COM库中的SphereObject程序见Intra3D-COM\Layer2\SphereObject.h和SphereObject.cpp。

SphereObject有两个接口:

ISphereObject与IGraphicalObject。

ISphereObject的定义如下:

interfaceISphereObject:

IDispatch

{

HRESULTSetSphere(floatradius,[defaultvalue(32)]intslices);

HRESULTSetMaterial(IMaterial*pMat);

HRESULTSetTexture(ITexture2D*pTex);

HRESULTSetDrawMode(EnumDrawModemode);

};

枚举类型EnumDrawMode定义如下:

typedefenum

{

SOLID=1,

WIRE=2,

}EnumDrawMode;

SphereObject的两个接口ISphereObject与IGraphicalObject是由类CSphereObject实现的:

classCSphereObject:

publicCComObjectRootEx,

publicCComCoClass,

publicIDispatchImpl,

publicIDispatchImpl

{

public:

CSphereObject();

DECLARE_REGISTRY_RESOURCEID(IDR_SPHEREOBJECT)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSphereObject)

COM_INTERFACE_ENTRY(ISphereObject)

COM_INTERFACE_ENTRY2(IDispatch,ISphereObject)

COM_INTERFACE_ENTRY(IGraphicalObject)

END_COM_MAP()

public:

//-----------------------------ISphereObject接口------------------------------

STDMETHOD(SetSphere)(floatradius,/*[defaultvalue(32)]*/intslices);

STDMETHOD(SetDrawMode)(EnumDrawModemode);

STDMETHOD(SetMaterial)(IMaterial*pMat);

STDMETHOD(SetTexture)(ITexture2D*pTex);

//-----------------------------IGraphicalObject接口-------------------------------

STDMETHOD(Draw)();

STDMETHOD(GetBoundBox)(float*dx,float*dy,float*dz,float*cx,float*cy,float*cz);

STDMETHOD(GetBoundSphere)(float*radius,float*cx,float*cy,float*cz);

STDMETHOD(GetMinMax)(float*minX,float*minY,float*minZ,

float*maxX,float*maxY,float*maxZ);

virtualvoidFinalRelease(void);//类CComObjectRootEx的虚函数

protected:

floatm_fRadius;//球体半径

intm_iSlices;//球体经纬等份数

intm_iDrawMode;//绘制模式,取SOLID或者WIRE

IMaterial*m_pMaterial;//引用材质

ITexture2D*m_pTexture;//引用纹理

};

注意此处的成员变量m_pMaterial是IMaterial接口指针,m_pTexture是ITexture接口指针,FinalRelease是基类CComObjectRootEx的虚函数。

CSphereObject:

:

CSphereObject(void)

{

m_fRadius=1.0;

m_iSlices=32;

m_iDrawMode=SOLID;

m_pMaterial=NULL;

m_pTexture=NULL;

}

STDMETHODIMPCSphereObject:

:

SetMaterial(IMaterial*pMat)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

if(m_pMaterial!

=NULL)

m_pMaterial->Release();

m_pMaterial=pMat;

if(pMat!

=NULL)

m_pMaterial->AddRef();

returnS_OK;

}

STDMETHODIMPCSphereObject:

:

SetTexture(ITexture2D*pTex)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

if(m_pTexture!

=NULL)

m_pTexture->Release();

m_pTexture=pTex;

if(pTex!

=NULL)

m_pTexture->AddRef();

returnS_OK;

}

voidCSphereObject:

:

FinalRelease(void)

{

if(m_pMaterial!

=NULL)

m_pMaterial->Release();

if(m_pTexture!

=NULL)

m_pTexture->Release();

}

STDMETHODIMPCSphereObject:

:

SetSphere(floatradius,intslices)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

m_fRadius=radius;

m_iSlices=slices;

returnS_OK;

}

STDMETHODIMPCSphereObject:

:

SetDrawMode(EnumDrawModemode)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

m_iDrawMode=mode;

returnS_OK;

}

STDMETHODIMPCSphereObject:

:

Draw(void)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

if(m_pMaterial!

=NULL)

{

floatcolor[3];

m_pMaterial->GetDiffuseColor(color+0,color+1,color+2);

glColor3fv(color);

m_pMaterial->Apply();

}

if(m_pTexture!

=NULL)

{

glEnable(GL_TEXTURE_2D);

m_pTexture->Apply();

}

if(m_iDrawMode==SOLID)

DrawSolidSphere(m_fRadius,m_iSlices);

elseif(m_iDrawMode==WIRE)

{

intflag;

glGetIntegerv(GL_LIGHTING,&flag);

if(flag)glDisable(GL_LIGHTING);

DrawWireSphere(m_fRadius,m_iSlices);

if(flag)glEnable(GL_LIGHTING);

}

if(m_pTexture!

=NULL)

glDisable(GL_TEXTURE_2D);

returnS_OK;

}

STDMETHODIMPCSphereObject:

:

GetMinMax(float*minX,float*minY,float*minZ,

float*maxX,float*maxY,float*maxZ)

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

*minX=*minY=*minZ=-m_fRadius;

*maxX=*maxY=*maxZ=m_fRadius;

returnS_OK;

}

STDMETHODIMPCSphereObject:

:

GetBoundSphere(float*radius,float*cx,float*cy,float*cz)

{

AFX_MANAGE_STATE(AfxGetStaticModuleStat

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1