视图V3d_View创建成功,接下来就是三维场景渲染。在原生窗口的绘制时间中,调用V3d_View::Redraw()方法,实现三维场景渲染。
void SinnDockView::paintEvent( QPaintEvent* /*theEvent*/ )
{
if(!myView.IsNull())
{
myView->Redraw();
}
}
V3d_View::Redraw()
{
Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
aStructureMgr->RecomputeStructures();
--- 准备好可渲染Struct
AutoZFit();
--- 设置好相机的远近裁剪面
myView->Redraw();
--- 调用OpenGl_View代理子对象,进入实质的渲染流程
}
渲染大体逻辑如下:
V3d_View::Redraw()
{
AutoZFit();
--- 设置好相机的远近裁剪面
}
OpenGl_View::Redraw()
{
myWorkspace->Activate()
--- 激活工作空间:把上下文设置为当前上下文;设置裁剪坐标到窗口坐标的变换行为。
aCtx = myWorkspace->GetGlContext();
releaseSrgbResources (aCtx);
initTextureEnv (aCtx);
aCtx->ShaderManager()->UpdateSRgbState();
--- 释放SRGB颜色空间资源、初始化纹理环境、更新SRGB状态。
aCtx->FetchState();
--- 检索上下文状态
aProjectType = myCamera->ProjectionType();
prepareFrameBuffers (aProjectType)
--- 准备帧缓存
for (myLights:aLightIter)
{
aLight = aLightIter.Value();
aShadowMap->SetLightSource (aLight);
renderShadowMap (aShadowMap);
}
--- 绘制阴影地图
。。。。。。。。。。
}
OpenGl_View::redraw
{
theReadDrawFbo->BindBuffer (aCtx);
--- 绑定帧缓存区(离屏渲染):
aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
aCtx->SetFrameBufferSRGB (true);
theReadDrawFbo->SetupViewport (aCtx);
--- 设置视口大小(glViewport)
。。。。。。
}
OpenGl_View::redraw
{
myBVHSelector.SetViewVolume (myCamera);
myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio());
myBVHSelector.CacheClipPtsProjections();
--- 更新视锥体剔除参数
}
OpenGl_View::redraw
{
aContext->SetCamera (myCamera);
--- 设置相机
}
视图绘制对象的顺序是:先绘制背景---> 接着绘制可渲染对象 ---> 最后绘制窗口坐标。 这里主要说明一下绘制可渲染对象的渲染过程。
在Opencascade中,最常用的可渲染对象是AIS_Shape;AIS_Shape继承了PrsMgr_PresentabelObject。每一个可渲染对象,有一个与图形系统交互的代理子对象Graphic3d_Struct。对于OpenGL图形系统,改代理子对象是OpenGl_Struct。
AIS_Shape 通过OpenGl_Struct,创建可用于OpenGl渲染绘制的图元。
在Opencascade中,调用AIS_InteractiveContext的Display方法来显示一个可渲染对象,其过程如下:
Graphic3d_ZLayerId_Default = 0 缺省值
Graphic3d_ZLayerId_Top = -2
Graphic3d_ZLayerId_Topmost = -3
Graphic3d_ZLayerId_TopOSD = -4
Graphic3d_ZLayerId_BotOSD = -5
Graphic3d_TOPA_POINTS 独立点
Graphic3d_TOPA_SEGMENTS 线段,每2个点定义一条线段
Graphic3d_TOPA_POLYLINES 多线,每个新点和其之前的点定义一条线段
Graphic3d_TOPA_TRIANGLES 三角形,每3个点定义一个三角形
Graphic3d_TOPA_TRIANGLESTRIPS 三角形条带,每个新点与其之前的2个顶点定义一个三角形
Graphic3d_TOPA_TRIANGLEFANS 三角形扇形,新点与其之前的点、第一个点定义个三角形
3.调用OpenGl_View的Display方法把OpenGl_Struct按其ZLayerId到视图的合适ZLayer中
渲染可渲染对象,就是渲染可渲染对象创建的渲染Struct,OpenGl图形系统对应的就是OpenGl_Struct。主要逻辑在OpenGl_View::renderStructs。渲染步骤如下:
myZLayers.UpdateCulling (myWorkspace, theToDrawImmediate);
首先绘制Layer中的不透明Struct到帧缓存(aMainFbo)
软后绘制Layer中的透明Struct 到OIT缓存(aMainFboOit)。
渲染的最后一步,是把OpenGl渲染到缓存的图像,绘制到显示窗口。
aCtx->SetReadDrawBuffer (GL_BACK);
--- 设置读写缓存
eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
--- 帧缓存内容绘制到窗口