Актуальный ландшафт OpenGL View на iOS - PullRequest
4 голосов
/ 24 сентября 2011

Я портирую движок на основе C ++ с Android на iOS, и у меня есть несколько вопросов о том, как работает альбомный режим на устройствах iOS.

Я могу успешно запустить устройство в альбомном режиме, но мой кадровый буфер остается в портретном режиме, независимо от того, как я его поворачиваю (или принудительно поворачиваю). Например, я бы ожидал разрешение 960x640 вместо стандартного 320x480.

Я исследовал это и увидел, что некоторые люди делают это, но явно поворачивают сцену, используя OpenGL, что означает, что фактическая ось не была в альбомном режиме, что для меня - уродливый обходной путь.

Ответы [ 2 ]

5 голосов
/ 26 сентября 2011

Убедитесь, что ваш OpenGL UIView подключен к UIViewController и не вставлен непосредственно в UIWindow. Для этого создайте собственный контроллер представления:

@interface MyViewController : UIViewController
@end

@implementation MyViewController
- (void)loadView {
    // Create your EAGL view
    MyEAGLView *eaglView = [[MyEAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
    self.view = eaglView;
    [eaglView release];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}
@end

Затем добавьте его в окно вашего приложения через AppDelegate:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    MyViewController *viewController = [[MyViewController alloc] init];
    [self.window setRootViewController:viewController];
    [viewController release];
    [self.window makeKeyAndVisible];
}    

self.window - это просто UIWindow приложения, вам, возможно, придется изменить его, если вы сохраните окно в другом месте.

После этого UIViewController заботится о поворотах и ​​изменении размера вашего представления, когда устройство поворачивается, и вы можете переопределить метод layoutSubviews в вашем объекте MyEAGLView для обработки изменения размера контекста OpenGL. Вы также можете посмотреть пример кода Apple для приложений OpenGL, поскольку он корректно обрабатывает этот материал.

0 голосов
/ 30 марта 2016

Вы можете повернуть вывод 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 переворачивает видеоокно - не поворачивает его.Для поворота вы должны сначала выбрать матрицу 4 на основе ориентации, а затем заменить переменную предпочитаемое вращение числом градусов (в радианах, формула которого также указана).

Существует многоспособы поворота вида, слоя, объекта и т. д .;но если вы визуализируете изображение через OpenGL, вам следует выбрать этот метод, и только этот метод.

...