OpenGL旋转屏幕时需要重新配置什么

时间:2013-12-02 11:15:17

标签: ios opengl-es

我必须为iOS制作一个lib。有一个必须支持旋转的UIView类。这个类目前使用OpenGL ES 1.0绘制所有内容。视图处于纵向方向时没有问题。但是当我旋转设备/模拟器时,我绘制的所有内容都变得模糊,并不多。我检查但他们似乎并没有被拉伸。所以我的理由是我需要在旋转后重新配置OpenGL中的某些内容,就像我的渲染缓冲区一样。但我不确切知道哪一个。我是OpenGL的新手,因为我主要使用Web / Core功能。

所以,如果有人能就此事给我任何建议,请。当我使用OpenGL旋转屏幕时,我通常应该这样做? 如果我需要为此案例提供任何代码,请告诉我。

谢谢

2 个答案:

答案 0 :(得分:1)

我不知道这是否能解决你的问题,但至少它解决了我的问题,所以我会分享我发现的问题。我的代码是通过OpenTK在C#中,但OpenGLES接口是相同的,所以我很确定你可以在你的代码中做同样的事情。

当旋转设备时,必须使用横向尺寸重新创建渲染缓冲区。如果不这样做,EAGL上下文将拉伸渲染缓冲区并使其适合屏幕。然后,您将在垂直轴上压缩像素,并在水平轴上拉伸像素。

当我检测到旋转(WillRotate

时,这是我重新创建渲染缓冲区(在C#中)的方法
public void ResizeFrameBuffer(int newWidth, int newHeight)
{
    DeviceWidth = newWidth;
    DeviceHeight = newHeight;

    Size = new System.Drawing.Size(DeviceWidth, DeviceHeight);
    Bounds = new System.Drawing.RectangleF(0, 0, DeviceWidth, DeviceHeight);

    MakeCurrent();

    GL.DeleteRenderbuffers(1, ref renderbuffer);

    GL.BindFramebuffer(FramebufferTarget.Framebuffer, Framebuffer);
    GL.GenRenderbuffers(1, out renderbuffer);
    GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer);
    EAGLContext.RenderBufferStorage((uint)RenderbufferTarget.Renderbuffer, (CAEAGLLayer)Layer);
    GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, RenderbufferTarget.Renderbuffer, renderbuffer);
    GL.Viewport(0, 0, DeviceWidth, DeviceHeight);
    GL.Scissor(0, 0, DeviceWidth, DeviceHeight);

    Frame = new System.Drawing.RectangleF(0, 0, DeviceWidth, DeviceHeight);
}

question I posted on the Game Development SE中有更多信息,因此您可能也想检查一下。

答案 1 :(得分:0)

您可以按如下方式在顶点着色器中旋转OpenGL输出:

#version 300 es


in vec4 position;
in mediump vec4 texturecoordinate;

in vec4 color;

uniform float preferredRotation;

out mediump vec2 coordinate;

void main()
{
    //const float pi = 4.0 * atan(1.0);
    //float radians  = (( -90.0 ) / 180.0 * pi );

    // Preferred rotation of video acquired, for example, by:
    // AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
    // CGAffineTransform preferredTransform = [videoTrack preferredTransform];
    // self.glKitView.preferredRotation = -1 * atan2(preferredTransform.b, preferredTransform.a);

    // Preferred rotation for both portrait and landscape           
    mat4 rotationMatrix = mat4( cos(preferredRotation), -sin(preferredRotation), 0.0, 0.0,
                                sin(preferredRotation),  cos(preferredRotation), 0.0, 0.0,
                                0.0,                     0.0,                    1.0, 0.0,
                                0.0,                     0.0,                    0.0, 1.0);

    // Mirror vertical (portrait only)
    mat4 rotationMatrix = mat4( cos(preferredRotation),  sin(preferredRotation), 0.0, 0.0,
                               -sin(preferredRotation),  cos(preferredRotation), 0.0, 0.0,
                                0.0,           0.0,          1.0, 0.0,
                                0.0,           0.0,          0.0, 1.0);

    // Mirror horizontal (landscape only)
    mat4 rotationMatrix = mat4( 1.0, 0.0,                     0.0,                    0.0,
                                0.0, cos(preferredRotation), -sin(preferredRotation), 0.0,
                                0.0, sin(preferredRotation),  cos(preferredRotation), 0.0,
                                0.0, 0.0,                     0.0,                    1.0);

    // Mirror vertical (landscape only)
    mat4 rotationMatrix = mat4( cos(preferredRotation), 0.0, sin(preferredRotation), 0.0,
                                0.0,                    1.0, 0.0,                    0.0,
                               -sin(preferredRotation), 0.0, cos(preferredRotation), 0.0,
                                0.0,                    0.0, 0.0,                    1.0);

    gl_Position = position * rotationMatrix;
    coordinate = texturecoordinate.xy;
}

显然,您只选择一个矩阵4,具体取决于视频的方向,然后是旋转。每个矩阵4翻转视频窗口 - 不旋转它。对于旋转,您必须首先根据方向选择matrix4,然后将preferredRotation变量替换为度数(以弧度表示,也提供其公式)。

有很多方法可以旋转视图,图层,对象等;但是,如果你是通过OpenGL渲染图像,那么你应该选择这种方法,而只选择这种方法。

相关问题