按照模板效果的3个基本要素,前2个要素非常简单,只要记住进行设置即可。
窗口模板效果开关采用如下代码设置即可:
pWindow_myWindow->setNumStencilBits(1);
通道绘制区域设置采用如下代码即可:
pChannel_myChannel->setDrawArea(0.00,1.00,0.00,1.00);
参数值采用了默认设置,也就是表示绘制区域是整个窗口。开发者也可以自己尝试[0,1]的合理值,试试效果。比如:
pChannel_myChannel->setDrawArea(0.01,0.99,0.01,0.99);
可以设置绘制区域为窗口的中间[0.01,0.99]的区域,四周留下黑色边框,如图9.11.2所示。
模板显示效果的核心设计在于通道订阅类的设计。
首先,在PublicMember 类里面设计两个静态浮点数,默认值为0.5,表示圆形模板的中心位于绘制区域的中心,用于控制圆形模板的中心位置:
//圆形模板中心坐标
float PublicMember::drawX=0.5;
float PublicMember::drawY=0.5;
图9.11.2 设置通道绘制区域效果
其次,进行窗口订阅类的设计,其详细代码如图9.11.3所示。
单通道模板效果通道订阅类myChannelStencil 继承于通道订阅类vsChannel::Subscriber,实现原有的两个虚函数。
虚函数 virtual void notify(vsChannel::Event event,const vsChannel *channel,vrDrawContext *context)是主要的功能设计区。这里首先定义了一个模板元素 stencilTestElement,然后在vsChannel::EVENT_PRE_DRAW 事件中处理全部事情,其他事件则不再进行特殊处理。
由于OpenGL 没有直接绘制圆形的函数,就利用静态变量只进行一次赋值的特性,准备了一个包含37个元素的数组,每个元素包含x 和y 两个值,也就是平面上的37个点,这37个点是圆形模板上的37个点,从而通过绘制扇形得到圆形。
然后,设置通道的基本颜色,设置为蓝色:
channel->getVrChannel()->setClearColor(0.0f,0.0f,1.0f,1.0f);
启用通道的绘制上下文:
channel->getVrChannel()->apply(context);
接下来,允许重新设置图形状态,并启用其默认值:
context->pushElements(true);
模板效果只对平面起作用,需要设置相关项目:
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0,1.0,0.0,1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
清理模板缓冲区的值,并设置为0:
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
设置并启用模板元素值,其他值均被模板值代替:
stencilTestElement.m_enable=true;
stencilTestElement.m_mode=vrStencilTest::MODE_ALWAYS;
stencilTestElement.m_ref=1;
stencilTestElement.m_mask=1;
stencilTestElement.m_fail=vrStencilTest::OPERATION_REPLACE;
stencilTestElement.m_dfail=vrStencilTest::OPERATION_REPLACE;
stencilTestElement.m_dpass=vrStencilTest::OPERATION_REPLACE;
context->setElement(vrStencilTest::Element::Id,&stencilTestElement);//启用模板值
绘制模板显示的形状,这里绘制为圆形:
glBegin(GL_TRIANGLE_FAN);
for (i=0;i<numVertices;i++)(www.daowen.com)
glVertex2f(PublicMember::drawX + vertex[i][0],PublicMember::drawY + vertex[i][1]);
glEnd();
其中的PublicMember::drawX 和PublicMember::drawY 代表圆心位置,默认值为绘制区域中心,后面可以在键盘事件中修改它们的值,以便于控制模板特效的显示位置。
设置并启用模板元素值,在绘制的圆形区域内,场景值得以保持:
context->popElements(false);
stencilTestElement.m_enable=true;
stencilTestElement.m_mode=vrStencilTest::MODE_EQUAL;
stencilTestElement.m_ref=1;
stencilTestElement.m_mask=1;
stencilTestElement.m_fail=vrStencilTest::OPERATION_KEEP;
stencilTestElement.m_dfail=vrStencilTest::OPERATION_KEEP;
stencilTestElement.m_dpass=vrStencilTest::OPERATION_KEEP;
context->setElement(vrStencilTest::Element::Id,&stencilTestElement);
至此,单通道模板效果的设计全部完成,所有设计均在vsChannel::EVENT_PRE_DRAW事件中完成,详细代码如图9.11.3所示。
图9.11.3 单通道模板效果通道订阅类的设计
单通道模板效果设计完成后,还需要在主线程中进行启用,才会有实际效果。为了使用方便,需要预先定义一个通道静态变量PublicMember::MainChannel。整个启用过程是在VP的主线程中配置完成的,主要是为通道事件EVENT_PRE_DRAW 和EVENT_POST_DRAW 添加处理程序。
首先,获取通道,并保存于通道指针中:
PublicMember::MainChannel=vpChannel::find("myChannel");
PublicMember::MainChannel->ref();
其次,实例化一个模板特效通道订阅类:
myChannelStencil *myChStencil=new myChannelStencil();
最后,为通道添加订阅者事件及其处理程序:
当然,在主线程退出时,可以移除订阅者:
详细代码如图9.11.4所示。
图9.11.2 模板通道订阅类在主线程中的使用
运行结果如图9.11.5(a)所示。
在键盘的左移键功能中减小PublicMember::drawX的值,使模板圆形左移,其效果如图9.11.3(b)所示当然,右移与此类似。
在键盘的下移键功能中减小PublicMember::drawY的值,使模板圆形下移,其效果如图9.11.3(d)所示当然,上移与此类似。
图9.11.5 单通道模板效果
为了更好地体现模板效果,需要重新设计键盘函数的功能。这里增加了一个静态float 类型的变量PublicMember::m_magnification,用于控制放大倍数。
放大与缩小效果则放在了字母m 功能之下,PublicMember::m_magnification 默认为1,当其值被修改时,通过修改通道的FOV 角度值实现场景的放大与缩小:
PublicMember::MainChannel->setFOVSymmetric(45.0/PublicMember::m_magnification,-1.0f);
PublicMember::MainChannel ->setLODVisibilityRangeScale(1.0f/ PublicMember::m_ magnification);
键盘函数的详细代码如图9.11.6所示。
图9.11.6 单模板效果的键盘函数
效果如图9.11.5(c)所示,通道的FOV 角度默认为45°,修改PublicMember::m_magnification的值也就能修改通道的FOV 角度,从而实现场景的放大与缩小。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。