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

2024-03-26 23:40

本文主要是介绍Opencascade 可视化--创建视图分析(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、创建视图

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

代码逻辑如下:

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 可视化--创建视图分析(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850249

相关文章

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

Python实现数据可视化图表生成(适合新手入门)

《Python实现数据可视化图表生成(适合新手入门)》在数据科学和数据分析的新时代,高效、直观的数据可视化工具显得尤为重要,下面:本文主要介绍Python实现数据可视化图表生成的相关资料,文中通过... 目录前言为什么需要数据可视化准备工作基本图表绘制折线图柱状图散点图使用Seaborn创建高级图表箱线图热

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

MySQL的触发器全解析(创建、查看触发器)

《MySQL的触发器全解析(创建、查看触发器)》MySQL触发器是与表关联的存储程序,当INSERT/UPDATE/DELETE事件发生时自动执行,用于维护数据一致性、日志记录和校验,优点包括自动执行... 目录触发器的概念:创建触www.chinasem.cn发器:查看触发器:查看当前数据库的所有触发器的定

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3

Django中的函数视图和类视图以及路由的定义方式

《Django中的函数视图和类视图以及路由的定义方式》Django视图分函数视图和类视图,前者用函数处理请求,后者继承View类定义方法,路由使用path()、re_path()或url(),通过in... 目录函数视图类视图路由总路由函数视图的路由类视图定义路由总结Django允许接收的请求方法http