先看看整体,以及进度

第三天的内容,主要讲根据窗口参数建立图形上下文设备

建立一个全屏显示的图形设备





这个WindowingSystemInterface是纯虚基类,也就是下一步就要父类调用子类了。

获取或新建显示设置


各成员变量

成员变量的各种结构体类型




默认设置函数

可以从系统环境变量读

也可以从命令行读

但是一定在设置图像上下文前设定好显示设置。
这个显示设置类是单例,获取或者新建

获取摄像机的投影坐标系参数




![]()


读取环境变量,按照hostName:0.0格式解析为系统的主机名称(hostName),显示数displayNum(在win32下必须为0)和屏幕数screenNum(0或者其他数字)





获取显示器个数

这里转向了子类Win32WindowingSystem


单屏幕,获取屏幕分辨率



枚举显示设备数组(只要桌面的,不要远端的)


根据屏幕信息获得宽高

现在开始新建一个显示设备特性实例,设置图形窗口的特性值(根据立体显示模式不同,窗口特性中的模板位数等参量也会有所区分)

创建新的图形上下文,并将其设置给视景器的主摄像机


//获取windows系统API接口的实例


//如果屏幕数<0,则置零

开始准备用子类Win32WindowingSystem创建图形上下文了

根据traits->pbuffer,决定创建一个PixelBufferWin32或者GraphicsWindowWin32

![]()
![]()

这里选择了后者,只是,接下来让人惊喜的是,这不是windows程序设计中的第一个例子,创建最简单的windows程序么?很熟悉啊



到此,windows窗口注册成功。
接下来,创建GraphicsWindowWin32


通过基类,先创建一个事件队列,并绑定

基类们的构造函数开始了


除了初始化变量外,也要准备多线程了,初始化锁了


原来是用的临界区,用户级的,先初始化临界区


线程安全引用计数


新建一个线程阻塞器,用途是阻塞线程执行,直至release()唤醒,释放之前阻塞的线程

![]()

跟过去,看看如何阻塞的。把封装后的类的伪装都扒开。懒得去记忆这些东西。



这个block类的几个成员变量 Mutex _mut;已经看过了,是个临界区
Condition _cond;是什么?

有个方法wait(),如何等待的?跟过去,原来是通过事件和信号量方式





构造函数时就创建了这个事件,初始化完其他线程后激活事件,让等待这个事件的其他线程运行,

递增信号量的当前资源技术,每次1个。
还有个ScopedLock,这个锁锁的好,构造时创建,析构时释放。函数体内写就OK

突然感觉离题万里了。拉回来,注册图形上下文特性


上锁加图形上下文特性


![]()
OpenThreads::ReentrantMutex派生于OpenThreads::Mutex
![]()
成员变量


获取局部存储区的thread指针

一开始局部存储区为空,且上锁数为0,所以走else



进入临界区

返回0

赋值_threadHoldingMutex和_lockCount,

函数结束后自动析构

离开临界区

赋值后,_lockCount=1,_threadHoldingMutex仍为NULL。

拉回来,图形上下文数组把当前图形上下文加上。

![]()
![]()
这个函数结束,也析构解锁

层层返回

新建事件队列

开始计时


新建一个对象,记录交互事件。并设置鼠标Y轴朝向


关联事件队列和图形上下文


![]()

![]()
终于回到GraphicsWindowWin32构造函数了

![]()
设置鼠标指针


获取或创建鼠标指针

![]()
初始化,根据图形上下文特性创建windows窗口








//设置像素格式



已经注册了窗口,直接返回

//设置像素格式


关联图形上下文到windows窗口



![]()

![]()



放入活动窗口数组


![]()




















几天下来,终于返回了。创建新的图形上下文,并把它设置给视景器的主摄像机。





![]()
![]()
记录新建立的窗口设备的大小



设置主相机的透视投影参数



设置视口





















这是个回调

更新回调和事件回调

设置更新回调和事件回调数目



自动设置摄像机想要绘制和读取的缓存




好,终于第三天地完成了。
以最后一个结构体收尾

睡觉了

3万+

被折叠的 条评论
为什么被折叠?



