I remember when I picked up the iPad for the first time, I was most struck by the iBooks app with its naturalistic page turning. All the other "chips" were somehow not particularly impressive, but this ... it seemed like the embodiment of complete interactivity. Compared to regular graphical interfaces using standard GUI elements, interfaces using OpenGL animation is a new step in the development of user interfaces. Historical digression : the first to use the elements of animation in GUI Indy workstations by Silicon Graphics, which is the founder of the OpenGL language. On the desktops of these computers were three-dimensional menu buttons that, when pressed, turned over in 3D, opening lists of submenus of the same buttons. It was great and it was really beautiful. It is a pity that Silicon Graphics went into oblivion due to improper management, this company was really the first in many ways (OpenGL, STL, journaling file systems). Therefore, I will not sing the praises of Apple, they just introduced a well-forgotten old. But in fairness it should be noted that this was a breakthrough, because they set the trend and dull static interfaces, I hope, will soon be in the past.
So, OpenGL animation and GUI . By the nature of my work, I had to develop projects using OpenGL, so when I was faced with the need to create an animation that emulates turning over paper pages, I had two main tasks:
• sheet plane deformation algorithm • OpenGL and user interface integration ')
The project was developed for the MacOS X operating system using the basic frameworks and the Objective-C language.
Paper Sheet Algorithm The idea is taken from here . As a deformation algorithm, the cone equation is used. This algorithm was developed in research laboratories Xerox PARC back in 2004. The bending of a paper sheet is determined by the surface of a certain cone, by changing the parameters of which you can achieve the desired animation effect.
I will not go into the details of the description of the algorithm and trigonometry. Let me just say that he recalculates any 2D point P (x, y) of the plane of the sheet into 3D point T (x, y, z), using variable parameters A and θ. For those who want more details, there is a source code for a test project for iOS and OpenGL-ES.
OpenGL and user interface integration Animation methods used in user interfaces are usually implemented as follows:
initial state - animation frames - final state
That is, some initial and final states of the animated interface object are taken, the object itself usually either hides or overlaps with the object that renders the transition frames, at the end the renderer hides and shows the object in the final state.
When applied to flipped pages, the initial and final states correspond to two consecutive page spreads of the book. That is, the animation algorithm should be as follows:
- take the texture of the current page spread - scroll offscreen pages - take the texture of the next page spread from offscreen buffer - block the spread of the pages OpenGL renderer - run animation - at the end, hide the OpenGL renderer and show the next spread, which is located in offscreen.
I used the class as a OpenGL renderer. NSOpenGLView, which has its own OpenGL context and several convenient methods for managing this context.
Depending on the page turning direction, the renderer is initialized with four page textures, two static textures and two dynamic ones that are deformed using the above algorithm. Consider flipping the page from right to left:
The current spread: the left page is static, the right page is dynamic. The next turn: the left page is dynamic, the right page is static.
Below is the code for the controller that controls the page animation. The code is simplified and only manages page flipping.
// turn the page behind the scenes [ bookView flipPageOffScreen ] ;
// initialize the texture of the next page spread [ rendererView setAnimatedBack : [ self getPageTexture : PAGE_LEFT ] ] ; [ rendererView setStaticRight : [ self getPageTexture : PAGE_RIGHT ] ] ;
// finally show our renderer, overlapping the current spread // books with the same picture, only rendered in OpenGL [ rendererView setHidden : NO ] ; }
- ( void ) setCurrentProgress : ( NSAnimationProgress ) progress { // render animation, progress value changes from 0 to 1 [ rendererView updateTime : progress ] ; }
@end
Animation is easy to manage without a timer, such as using mouse or touchpad events. This achieves the effect of “dragging” the page; it is enough to send updateTime: messages from the event handler to the renderer.
I will not give the OpenGL renderer code, since it is banal. Mapping textures made with triangles stripes, added highlight scenes animation. So in conclusion, this is how it looks in work (I apologize for the quality):