OpenGL ES實(shí)踐教程(六)全景視頻獲取焦點(diǎn)

教程

OpenGL ES實(shí)踐教程1-Demo01-AVPlayer
OpenGL ES實(shí)踐教程2-Demo02-攝像頭采集數(shù)據(jù)和渲染
OpenGL ES實(shí)踐教程3-Demo03-Mirror
OpenGL ES實(shí)踐教程4-Demo04-VR全景視頻播放
OpenGL ES實(shí)踐教程5-Demo05-多重紋理實(shí)現(xiàn)圖像混合
其他教程請(qǐng)移步OpenGL ES文集

前言

有開(kāi)發(fā)者在群里問(wèn)如何實(shí)現(xiàn):

觀看VR視頻的時(shí)候,眼神停在菜單上霎奢,稍后會(huì)觸發(fā)事件饵逐,比如暫停穆端,重放功能

說(shuō)說(shuō)可能的方案:

  • 1困曙、添加外設(shè):采集眼球運(yùn)動(dòng)和眨眼操作恰矩,并通過(guò)無(wú)線通訊傳給手機(jī)记盒;
  • 2、離屏渲染:新建緩沖區(qū)枢里,把像素是否能操作編碼到顏色分量(RGBA均可)孽鸡,按照屏幕渲染的流程在新的緩沖區(qū)內(nèi)渲染,然后通過(guò)glReadPixel讀取對(duì)應(yīng)像素的操作栏豺;
  • 3彬碱、模擬計(jì)算:假設(shè)有一條直線從視點(diǎn)出發(fā),經(jīng)過(guò)焦點(diǎn)奥洼,最終與全景球面相交巷疼,通過(guò)計(jì)算交點(diǎn)是否在按鈕上確定是否聚焦成功;

方案1是理想的方案灵奖,但實(shí)際應(yīng)用開(kāi)發(fā)成本嚼沿,成本太高;
方案2需要離屏渲染瓷患,首先切換幀緩存導(dǎo)致GPU等待骡尽;其次,每次聚焦都要重繪(當(dāng)用戶一直移動(dòng)屏幕的時(shí)候擅编,需要不斷重繪)攀细;最后箫踩,glReadPixel是同步操作,對(duì)性能有較大的影響谭贪;
方案3是較為合理的實(shí)現(xiàn)方案境钟,僅需要CPU進(jìn)行少量的浮點(diǎn)變化運(yùn)算,不需要外設(shè)和離屏渲染俭识;
本文在OpenGL ES實(shí)踐教程4-Demo04-VR全景視頻播放的基礎(chǔ)上慨削,添加簡(jiǎn)單的色塊,單焦點(diǎn)進(jìn)入色塊時(shí)進(jìn)行變色套媚。

核心思路

通過(guò)計(jì)算全景球面上的點(diǎn)經(jīng)過(guò)旋轉(zhuǎn)投影后的位置缚态,來(lái)確定當(dāng)前焦點(diǎn)是否停留在按鈕上。

  • 實(shí)現(xiàn)1:從攝像機(jī)的視點(diǎn)O(0,0,0)到的焦點(diǎn)P(0.5,0.5,0.5)連接一條直線PO凑阶,求出直線與全景球面X2+Y2+Z^2=1上面的交點(diǎn)T猿规。
    當(dāng)攝像機(jī)旋轉(zhuǎn)的時(shí)候衷快,焦點(diǎn)P不斷變化宙橱,對(duì)新的焦點(diǎn)P’,按照上述的方式求出點(diǎn)T’蘸拔,判斷點(diǎn)T’是否在球面的按鈕區(qū)域师郑;

可以通過(guò)手寫(xiě),我們知道直線OP的方程為2x-1=2y-1=2z-1
聯(lián)合方程调窍,可以求出交點(diǎn)T(1/sqrt(3), 1/sqrt(3), 1/sqrt(3) )宝冕。
當(dāng)攝像機(jī)旋轉(zhuǎn)的時(shí)候,再求出對(duì)應(yīng)的交點(diǎn)即可邓萨。

  • 實(shí)現(xiàn)2:假設(shè)點(diǎn)P是按鈕的中心地梨,對(duì)點(diǎn)P進(jìn)行旋轉(zhuǎn)、投影等變換后缔恳,求出點(diǎn)P在屏幕上的位置宝剖,如果點(diǎn)P在焦點(diǎn)范圍內(nèi),則認(rèn)為聚焦歉甚;

demo采用的是實(shí)現(xiàn)2万细。

效果展示

具體細(xì)節(jié)

先把OpenGL ES實(shí)踐教程4-Demo04-VR全景視頻播放的工程拖過(guò)來(lái)。

1纸泄、添加表示按鈕的色塊

  • 在頂點(diǎn)著色器添加varying lowp vec3 varyOtherPostion變量赖钞,傳遞頂點(diǎn)數(shù)據(jù)到像素著色器;
  • 新建變量leftBottom聘裁、rightTop雪营、myTexture1表示按鈕的區(qū)域和按鈕的紋理;
varying lowp vec2 texCoordVarying;
varying lowp vec3 varyOtherPostion;
precision mediump float;
uniform sampler2D SamplerY;
uniform sampler2D SamplerUV;
uniform mat3 colorConversionMatrix;
uniform vec2 leftBottom;
uniform vec2 rightTop;
uniform sampler2D myTexture1;
void main()
{
    mediump vec3 yuv;
    lowp vec3 rgb;
    
    // Subtract constants to map the video range start at 0
    yuv.x = (texture2D(SamplerY, texCoordVarying).r);// - (16.0/255.0));
    yuv.yz = (texture2D(SamplerUV, texCoordVarying).ra - vec2(0.5, 0.5));
    
    rgb = colorConversionMatrix * yuv;
    
    if (varyOtherPostion.x >= leftBottom.x && varyOtherPostion.y >= leftBottom.y && varyOtherPostion.x <= rightTop.x && varyOtherPostion.y <= rightTop.y && varyOtherPostion.z > 0.0) {
        lowp vec2 test = vec2((varyOtherPostion.x - leftBottom.x) / (rightTop.x - leftBottom.x), 1.0 -  (varyOtherPostion.y - leftBottom.y) / (rightTop.y - leftBottom.y));
        lowp vec4 otherColor = texture2D(myTexture1, test);
        otherColor.a = 0.5;
        gl_FragColor = otherColor * otherColor.a + vec4(rgb, 1.0) * (1.0 - otherColor.a);
    }
    else {
        gl_FragColor = vec4(rgb, 1.0);
    }
}
  • 在中LYOpenGLView.m中獲取對(duì)應(yīng)的變量并賦值衡便;
glUniform1i(uniforms[UNIFORM_TEXTURE1], 2);
glUniform2f(uniforms[UNIFORM_LEFT_BOTTOM], -0.25, -0.25);
glUniform2f(uniforms[UNIFORM_RIGHT_TOP], 0.25, 0.25);

2献起、監(jiān)聽(tīng)手指移動(dòng)并判斷聚焦

  • 添加初始點(diǎn)position,我們假設(shè)是(0, 0, -1, 1);
GLKVector4 position = GLKVector4Make(0, 0, -1, 1);
  • 計(jì)算變化矩陣征唬,求出變換后的點(diǎn)targetPosition捌显;
    GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
    modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, horizontalDegree);
    modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, verticalDegree);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(90, CGRectGetWidth(self.bounds) * 1.0 / CGRectGetHeight(self.bounds), 0.01, 10);
    GLKVector4 position = GLKVector4Make(0, 0, -1, 1);
    GLKVector4 targetPosition = GLKMatrix4MultiplyVector4(GLKMatrix4Multiply(projectionMatrix, modelViewMatrix), position);
  • 判斷是否聚焦成功;(點(diǎn)(0.2, -0.05, -1.0)是根據(jù)初始點(diǎn)算出來(lái)的聚焦中心位置总寒,如果初始點(diǎn)變化扶歪,這個(gè)點(diǎn)也要跟著變化)
  float dif = 0.3;
  if (fabs(targetPosition.x - 0.2) <= dif &&
      fabs(targetPosition.y + 0.05) <= dif &&
      fabs(targetPosition.z + 1.00) <= dif &&
      1) {
      [self setupFirstTexture:@"select"];
  }
  else {
      [self setupFirstTexture:@"normal"];
  }

總結(jié)

本文存在各種不嚴(yán)謹(jǐn)?shù)牡胤剑瑑H供參考摄闸。
中間在手動(dòng)計(jì)算空間直線方程的時(shí)候善镰,還計(jì)算錯(cuò)誤,通過(guò)空間直線方程得到糾正年枕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炫欺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子熏兄,更是在濱河造成了極大的恐慌品洛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摩桶,死亡現(xiàn)場(chǎng)離奇詭異桥状,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)硝清,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門辅斟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芦拿,你說(shuō)我怎么就攤上這事士飒。” “怎么了蔗崎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵酵幕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蚁趁,道長(zhǎng)裙盾,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任他嫡,我火速辦了婚禮番官,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钢属。我一直安慰自己徘熔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布淆党。 她就那樣靜靜地躺著酷师,像睡著了一般讶凉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上山孔,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天懂讯,我揣著相機(jī)與錄音,去河邊找鬼台颠。 笑死褐望,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的串前。 我是一名探鬼主播瘫里,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼荡碾!你這毒婦竟也來(lái)了谨读?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坛吁,失蹤者是張志新(化名)和其女友劉穎劳殖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體阶冈,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闷尿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年塑径,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了女坑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡统舀,死狀恐怖匆骗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情誉简,我是刑警寧澤碉就,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站闷串,受9級(jí)特大地震影響瓮钥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烹吵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一碉熄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肋拔,春花似錦锈津、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)性誉。三九已至,卻和暖如春茎杂,著一層夾襖步出監(jiān)牢的瞬間错览,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工煌往, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝗砾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓携冤,卻偏偏與公主長(zhǎng)得像悼粮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子曾棕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容