Opencascade 可视化--创建视图分析(二)

一、创建视图

创建一个Opencascade视图,过程如下:

Opencascade 可视化--创建视图分析(二)_第1张图片

代码逻辑如下:

Handle(Aspect_DisplayConnectionaDisplayConnection = new Aspect_DisplayConnection();

if (GetGraphicDriver().IsNull())

{

GetGraphicDriver() = new OpenGl_GraphicDriver(aDisplayConnection);

}

--- 创建图形系统驱动

myViewer = new V3d_Viewer(GetGraphicDriver());

myView = myViewer->CreateView();

--- 创建V3d_View

Handle(WNT_Windowwind = new WNT_Window((Aspect_Handlehwnd);

--- 根据已有窗口句柄,创建原生窗口

myView->SetWindow(wind);

---- 捆绑原生窗口

二、源码分析

2.1 创建图形系统OpenGl_GraphDriver

OpenGl_GraphDriver 通过EGL(EGL是地产原生窗口与Khronos渲染API(例如OpenGL ES,OpenVG等)之间的接口)建立OpenGl与原生窗口系统(例如:微软Windows,MacOS,Linux XServer)的联系、创建绘制上下文。OpenGl_GraphDriver的初始化函数(为了便于理解,去掉了一些不关键代码):

Standard_Boolean OpenGl_GraphicDriver::InitContext()

{

myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY);

------ 建立本地系统和 OpenGL ES 的连接

   EGLint aVerMajor = 0; EGLint aVerMinor = 0;

   eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor)

---- 初始化

   myEglConfig = chooseEglSurfConfig ((EGLDisplay )myEglDisplay);

---- chooseEglSurfConfig对eglChooseChofig进行了封装,作用是确定Surface(绘制区域)

的配置。

   EGLint* anEglCtxAttribs = NULL;

   eglBindAPI (EGL_OPENGL_API) != EGL_TRUE

      ---- 绑定OpenGl

myEglContext = eglCreateContext (myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs);

--- 创建EGL上下文

  myIsOwnContext = Standard_True;

  return Standard_True;

}

2.2 创建视图V3d_View

创建V3d_View的主要逻辑在V3d_View构造函数中,主要做两件事情:1. 调用驱动创建与OpenGl关联的代理子对象Openl_View;2.初始化相机等。

V3d_View构造函数:

V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)

{

myView = theViewer->Driver()->CreateView (theViewer->StructureManager());

--- 创建OpenGl_View

Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();

   aCamera->SetFOVy (45.0);

   aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);

   aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);

   aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)

     ? Graphic3d_Camera::Projection_Orthographic

    : Graphic3d_Camera::Projection_Perspective);

SetCamera (aCamera);

--- 初始化相机

}

驱动为V3d_View创建代理对象OpenGl_View:

Handle(Graphic3d_CView) OpenGl_GraphicDriver::CreateView

(const Handle(Graphic3d_StructureManager)& theMgr)

{

Handle(OpenGl_View) aView = new OpenGl_View (theMgr, this, myCaps, &myStateCounter);

  myMapOfView.Add (aView);

     ---- 创建OpenGl_View

}

2.3创建原生窗口WNT_Window

比较简单,不在此罗列。

2.4 捆绑原生窗口

捆绑原生窗口,本质上是为其代理子对象OpenGl_View捆绑原生窗口:

void V3d_View::SetWindow (const Handle(Aspect_Window)&  theWindow,

                          const Aspect_RenderingContext theContext)

{

myView->SetWindow (theWindow, theContext);

---- OpenGl_View 设置窗口

......

}

OpenGl_View 捆绑原生窗口主要做3事情:1. 创建一个渲染窗口捆绑原生窗口;2. 创建工作空间;3.初始化纹理环境。

void OpenGl_View::SetWindow (const Handle(Aspect_Window)& theWindow,

                             const Aspect_RenderingContext theContext)

{

myWindow = myDriver->CreateRenderWindow (theWindow, theContext);

--- 创建渲染窗口OpenGl_Window,绑定原生窗口

myWorkspace = new OpenGl_Workspace (this, myWindow);

--- 创建工作空间,OpenGl_Workspace 实现渲染图元、维护状态的方法。

initTextureEnv (myWorkspace->GetGlContext());

--- 初始化纹理环境

}

2.4.1创建一个渲染窗口捆绑原生窗口

Handle(OpenGl_Window) OpenGl_GraphicDriver::CreateRenderWindow

(const Handle(Aspect_Window)&  theWindow,

const Aspect_RenderingContext theContext)

{

 return new OpenGl_Window (this, theWindow, theContext, myCaps, aShareCtx);

}

OpenGl_Window::OpenGl_Window(...)

{

#if defined(HAVE_EGL)

EGLDisplay anEglDisplay = (EGLDisplay )theDriver->getRawGlDisplay();

   EGLContext anEglContext = (EGLContext )theDriver->getRawGlContext();

EGLConfig  anEglConfig  = (EGLConfig  )theDriver->getRawGlConfig();

anEglSurf = eglCreateWindowSurface

(anEglDisplay,

anEglConfig,

(EGLNativeWindowType )myPlatformWindow->NativeHandle(),--- 原生窗口句柄

NULL);

---- 创建屏幕渲染区:EGL窗口

myGlContext = new OpenGl_Context (theCaps))

myGlContext->Init

(

(Aspect_Drawable )anEglSurf,

(Aspect_Display )anEglDisplay,

(Aspect_RenderingContext )anEglContext, isCoreProfile

);

---- 创建OpenGl_Context(OpenGl上下文),并初始化:调用eglMakeCurrent,把EGL 上下设置为当前上下文;调用::glGetString (GL_VENDOR)检查当前OpenGL版本等信息。

Init();

--- 渲染窗口初始化

#endif

}

上下文初始化

OpenGl_Context::init(isCoreProfile)

{

GLint aMajor = 0, aMinor = 0;

     glGetIntegerv (GL_MAJOR_VERSION, &aMajor);

glGetIntegerv (GL_MINOR_VERSION, &aMinor);

...

--- 检索版本,确认当前版本支持情况。

myVendor = (const char* )::glGetString (GL_VENDOR);

--- 检索开发者

glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);

glGetIntegerv (GL_MAX_DRAW_BUFFERS,      &myMaxDrawBuffers);

glGetIntegerv (GL_MAX_COLOR_ATTACHMENTS, &myMaxColorAttachments);

glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);

glGetIntegerv (GL_MAX_TEXTURE_UNITS, &myMaxTexUnitsFFP);

glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);

glGetIntegerv (GL_MAX_VIEWPORT_DIMS, aMaxVPortSize);

glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);

glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);

glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);

glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);

glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);

glGetIntegerv (GL_STEREO, &aStereo);

glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);

--- 确定当前OpenGl支持特性

}

渲染窗口初始化

void OpenGl_Window::Init()

{

Activate();

--- 把上下文设为当前上下文

const Standard_Integer aViewport[4] = { 0, 0, myWidth, myHeight };

myGlContext->ResizeViewport (aViewport);

--- 修改视口大小

glDisable (GL_DITHER);

--- 关闭颜色抖动

glDisable (GL_SCISSOR_TEST);

--- 关闭裁剪测试

glMatrixMode (GL_MODELVIEW);

--- 指定GL_MODELVIEW 为当前矩阵

}

2.4.2 创建工作空间

OpenGl_Workspace::OpenGl_Workspace

(OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)

{

myGlContext = theWindow->GetGlContext()

myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);

--- 设置像素对齐方式

myGlContext->core11ffp->glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

--- 设置光照模式

myGlContext->core11fwd->glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);

--- 指定反走样点的采样质量

    if (myGlContext->caps->ffpEnable)

    {

        myGlContext->core11fwd->glHint (GL_FOG_HINT, GL_FASTEST);

--- 指定雾化计算的精度

}

myGlContext->core11fwd->glHint (GL_LINE_SMOOTH_HINT,    GL_FASTEST);

--- 指定反走样线段的采样质量

myGlContext->core11fwd->glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);

--- 指定反走样多边形的采样质量

}

你可能感兴趣的:(Opencascade学习,c++,windows)