1

I have a remote controller app, which is using CATiledLayer to display remote desktop. All drawing is made by drawRect: method. I have some really rare crashes when resizing remote screen's resolution.

I was trying to debug this issue but nothing helped, so (after receiving some advices from my smarter colleges) I decided to rewrite my code using CAEAGLLayer instead of CATiledLayer.

I was learning OpenGL ES 2.0, but all those tutorials are all about building 3D models. All I want is to be able to apply texture to appropriate area on View.

From what I was reading and thinking I consider that, when image to redraw will be received, I need to convert it to texture, get rect which should be redrew and generate verteces from it, then path varteces and texture to vertex shader.

Any ideas or advices are welcome.

(Please don't write something like:"Why you want to use OpenGL instead of CATiledLayer?" even if it's not best option I want to figure out how to make it work this way).

haawa
  • 3,078
  • 1
  • 26
  • 35

1 Answers1

0

Ok, since there were no responses to my question i will share what I've got. First of all I am using OpenGL ES 2.0.

1) I draw two triangles to cover whole screen like this

enter image description here

to store Vertices and triangles I use following structs (Color value is not used in my case):

typedef struct {
    float Position[3];
    float Color[4];
    float TexCoord[2];
} Vertex;

const Vertex Vertices[] = {
    {{1, -1, 0}, {1, 0, 0, 1}, {1, 0}},
    {{1, 1, 0}, {0, 1, 0, 1}, {1, 1}},
    {{-1, 1, 0}, {0, 0, 1, 1}, {0, 1}},
    {{-1, -1, 0}, {0, 0, 0, 1}, {0, 0}}
};

const GLubyte Indices[] = {
    0, 1, 2,
    2, 3, 0
};

2) After that done I wait for whole remote screen to load image and than I set that image of whole screen as texture using following code:

-(void)setupTextureFromCGImage:(CGImageRef)imageRef{

    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithBool:_snapshot.isImageMirrored],
                              GLKTextureLoaderOriginBottomLeft,
                              nil];

    NSError * error;
    GLKTextureInfo * info = [GLKTextureLoader textureWithCGImage:imageRef options:options error:&error];
    if (info == nil) {
        NSLog(@"Error loading file: %@", [error localizedDescription]);
        return;
    }
    self.effect.texture2d0.name = info.name;
    self.effect.texture2d0.enabled = true;
    _bigTexture = info.name;
    glBindTexture(GL_TEXTURE_2D, self.effect.texture2d0.name);
}

This code uses GLKit's GLKTextureLoader, however this can be simply replaced with glteximage2d().

After that view looks similar to this:

enter image description here

3) When the update received we need image of update and rect to know which part to update:

-(void)loadSubImageTextureImageBuffer:(const char *)buffer inRect:(CGRect)rect
{
CGRect rectGL = rect;
rectGL.origin.y = _snapshot.imageRect.size.height - (rectGL.origin.y +     rectGL.size.height);// convert coordinates from UIView's upper left to OpenGL's lower left

glTexSubImage2D(GL_TEXTURE_2D,
                    0,
                    rectGL.origin.x,
                    rectGL.origin.y,
                    rectGL.size.width,
                    rectGL.size.height,
                    GL_BGRA,
                    GL_UNSIGNED_BYTE,
                    buffer);
}

For drawing I use custom shaders not GLKView, they do nothing but mapping texture to vertices.

OpenGL drawing works faster then CATiledLayer, not extremely but still. There are some few glitches which I will investigate in the future.

Hope this will be useful for somebody. If you need some more details feel free to contact me haawaplus@gmail.com

P.S

For now I paused my CATiledLayer -> OpenGL ES investigation since i got some other work to do but I will update my answer when I will return to OpenGL.

haawa
  • 3,078
  • 1
  • 26
  • 35