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

相关文章

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Python创建Excel的4种方式小结

《Python创建Excel的4种方式小结》这篇文章主要为大家详细介绍了Python中创建Excel的4种常见方式,文中的示例代码简洁易懂,具有一定的参考价值,感兴趣的小伙伴可以学习一下... 目录库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriterwww.cppcns.c

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题

《解决IDEA使用springBoot创建项目,lombok标注实体类后编译无报错,但是运行时报错问题》文章详细描述了在使用lombok的@Data注解标注实体类时遇到编译无误但运行时报错的问题,分析... 目录问题分析问题解决方案步骤一步骤二步骤三总结问题使用lombok注解@Data标注实体类,编译时

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser