我一直在阅读OpenGL ES 2.0,SpriteKit和GLKit,但我仍然不知道如何解决以下问题。
问题:
1)创建一个圆柱形360空间,其中包含AVCaptureVideoPreviewLayer
,并在用户转动他/她的手机时旋转。不要过多关注旋转部分,它是我关注的OpenGL部分。比如,线条是如何绘制的?捕获后,图像如何放置在捕获的位置?这里使用了哪些组件? SpriteKit还是OpenGL?
2)基本上涉及(1)更深入地了解图像的放置方式。假设你有一个四元数,你会如何在3D空间中放置图像?
问题/关注:
我怎么能开始?如果有人能够简单地抽象出我应该做的事情,我会非常感激。甚至一些代码示例也会非常有用,因为我更好地理解它是用代码编写的。
问题是没有关于其中任何一个的实际文档,因此,如果您有任何参考(甚至书籍?),我将非常感激。
谢谢!
答案 0 :(得分:1)
我会尝试从最简单到最难回答,也许会指出你的方向。
glDrawElements有一个mode
参数,您可以选择GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES
等等...当您在OpenGL中绘图时,您想尝试最小化您执行的绘制调用次数,所以一次你得到了绘制状态集,尽可能在一次调用中提交尽可能多的几何体。基本上,在一次通话中绘制整个气缸的线。幸运的是,您只需要计算一次,然后用矩阵处理旋转。
接下来,您需要学习矩阵和着色器来绘制几何体。阅读NeHe教程,我认为他们已经针对OpenGLES2进行了更新。基本上,您有一个视图和投影矩阵(MVP)。投影是将3D几何投影到2d空间(并从-1..1标准化)。视图是旋转几何体的位置。我的建议是在Github或Apple Developer文档上找到一个例子并进行破解。另外,寻找OpenGL兼容的矩阵库。
当您第一次开始旋转时,使用拖动/滑动事件进行测试,以便您可以确定绕哪个轴旋转(y轴)以及左/右方向。然后将其连接到您的Motion事件(加速度计)。您的运动事件将记录在视图旋转中,并且每个矩阵都会更改(并且需要重新加载并重新上载到着色器中)。
(这是开始变硬的时候,哈哈)
将AVCaptureVideoPreviewLayer(AVLayer)放在EAGLView图层上,使其像示例中一样小。
接下来,您需要执行光线投射,以使用MVP矩阵确定AVLayer与圆柱相交的位置。嗯,实际上它稍微复杂一些,您必须将摄像机图像取消投影到视图空间,然后将其映射到圆柱体的纹理上。
让我重新开始。
如果您要从视角相机朝向AVLayer绘制一条线,它将在不同的点与圆柱相交。您可以将此交叉点拼接到圆柱体。你知道圆柱的几何(或方程),你知道视图的旋转。您知道AVLayer的大小和位置以及投影矩阵。
问题是这很慢。所以也许你认为你可以从气缸向后投射到相机,以便用AVLayer的交点投射圆柱体的UV坐标。然而,这会导致投影问题,并且图像看起来有些偏斜和奇怪。因为您是线性插值非线性投影。
你的下一个想法是尝试缓慢的方式并将每个像素投影到圆柱体的纹理。这看起来更好,但现在有漏洞。
最后,您意识到将两种方法和项目从圆柱体的纹理向后组合到视图中并且“读取”#39; AVLayer的交集。此外,因为您正在写入纹理,所以您决定使用RTT并让GPU完成繁重的工作(更快)。 AVLayer现在只是一个渲染到圆柱纹理的纹理。
坏消息是,虽然您可以在片段着色器中使用投影矩阵将平面AVLayer投影到圆柱形墙壁上,但我不知道那是什么。此外,您可能需要为横穿接缝的任何纹理渲染两次。
圆柱体具有您渲染的透明纹理。只需根据' final'的分辨率将U,V坐标添加到您的圆柱体。图片。绘制圆柱体两次,一次使用纹理(作为四边形),再一次(作为线条)。
查看有关FBO渲染目标(RTT)的NeHe教程。
此外,可以在没有OpenGL的情况下渲染到Cylinder的纹理,但是您需要在单独的线程中进行渲染,然后重新上传圆柱体的纹理。这将允许您使用数学来投影纹理并自己扫描。您可以使用模数运算符自动换行扫描线,而不必担心它会两次。
免责声明:我无法满足您的要求。我个人会在github上查看全景应用程序,并可能开始在那里添加其他东西(如圆柱体)。 YMMV