OSDN Git Service

HandBrake 0.6.0-test3
[handbrake-jp/handbrake-jp-git.git] / macosx / PictureGLView.mm
1 /* $Id: PictureGLView.mm,v 1.6 2004/03/08 12:39:49 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.m0k.org/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include <OpenGL/OpenGL.h>
8 #include <OpenGL/gl.h>
9 #include <math.h>
10
11 #include "PictureGLView.h"
12
13 #define PROUT 2.5
14
15 /* XXX This file needs some serious cleaning XXX */
16
17 GLuint    texture[2];
18 float     rotation;
19 float     translation;
20 uint8_t * truc;
21
22 @implementation HBPictureGLView
23
24 - (void) SetHandle: (HBHandle*) handle
25 {
26     fHandle = handle;
27 }
28
29 - (void) SetTitle: (HBTitle*) title
30 {
31     fTitle = title;
32
33     /* This is needed as the view's size may have changed */
34     [self clearGLContext];
35     [self openGLContext];
36 }
37
38 - (void) ShowPicture: (int) index animate: (int) how
39 {
40     if( fOldPicture ) free( fOldPicture );
41     fOldPicture = fPicture;
42
43     /* Get the picture */
44     uint8_t * tmp = HBGetPreview( fHandle, fTitle, index );
45
46     /* Make it be upside-down */
47     fPicture = (uint8_t*) malloc( 4 * ( fTitle->outWidthMax + 2 ) *
48                                   ( fTitle->outHeightMax + 2 ) );
49     uint8_t * in  = tmp;
50     uint8_t * out = fPicture +
51         4 * ( fTitle->outWidthMax + 2 ) * ( fTitle->outHeightMax + 1 );
52     for( int i = fTitle->outHeightMax + 2; i--; )
53     {
54         memcpy( out, in, 4 * ( fTitle->outWidthMax + 2 ) );
55         in  += 4 * ( fTitle->outWidthMax + 2 );
56         out -= 4 * ( fTitle->outWidthMax + 2 );
57     }
58     free( tmp );
59
60     /* ARGB -> RGBA */
61     uint32_t * p = (uint32_t*) fPicture;
62     for( int i = ( fTitle->outHeightMax + 2 ) *
63             ( fTitle->outWidthMax + 2 ); i--; )
64     {
65         *(p++) = ( ( (*p) & 0x00FFFFFF ) << 8 ) | 0xFF;
66     }
67
68     if( how == HB_ANIMATE_NONE )
69     {
70         [self drawRect: [self bounds]];
71         return;
72     }
73
74     in  = fOldPicture;
75     out = truc;
76     for( int i = fTitle->outHeightMax + 2; i--;  )
77     {
78         memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 );
79         in  += ( fTitle->outWidthMax + 2 ) * 4;
80         out += 1024 * 4;
81     }
82     glBindTexture( GL_TEXTURE_2D, texture[0] );
83     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024,
84                   1024, 0, GL_RGBA,
85                   GL_UNSIGNED_BYTE, truc );
86     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
87     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
88
89     in  = fPicture;
90     out = truc;
91     for( int i = fTitle->outHeightMax + 2; i--; )
92     {
93         memcpy( out, in, ( fTitle->outWidthMax + 2 ) * 4 );
94         in  += ( fTitle->outWidthMax + 2 ) * 4;
95         out += 1024 * 4;
96     }
97     glBindTexture( GL_TEXTURE_2D, texture[1] );
98     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 1024,
99                  1024, 0, GL_RGBA,
100                  GL_UNSIGNED_BYTE, truc );
101     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
102     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
103
104     glEnable( GL_TEXTURE_2D );
105     glShadeModel( GL_SMOOTH );
106     glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
107     glClearDepth( 1.0f );
108     glEnable( GL_DEPTH_TEST );
109     glDepthFunc( GL_LEQUAL );
110     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
111
112 #define ANIMATION_TIME 500000
113 #define FRAME_PER_SEC  50
114
115     rotation = 0.0;
116     float w = ( how == HB_ANIMATE_LEFT ) ? 1.0 : -1.0;
117     uint64_t date;
118     int64_t  wait;
119     for( ;; )
120     {
121         date = HBGetDate();
122         translation = - PROUT - cos( rotation * M_PI / 180 ) *
123                              ( 1 + w * tan( rotation * M_PI / 180 ) );
124         [self drawAnimation: how];
125
126         rotation += w * 90 * 1000000 / ANIMATION_TIME / FRAME_PER_SEC;
127         if( w * rotation >= 90.0 )
128         {
129             break;
130         }
131
132         wait = 1000000 / FRAME_PER_SEC - ( HBGetDate() - date );
133         if( wait > 0 )
134         {
135             HBSnooze( wait );
136         }
137     }
138
139     [self drawRect: [self bounds]];
140 }
141
142 - (id) initWithFrame: (NSRect) frame
143 {
144     fHandle    = NULL;
145     fTitle      = NULL;
146     fPicture    = NULL;
147     fOldPicture = NULL;
148
149     GLuint attribs[] =
150     {
151         NSOpenGLPFANoRecovery,
152         NSOpenGLPFAWindow,
153         NSOpenGLPFAAccelerated,
154         NSOpenGLPFADoubleBuffer,
155         NSOpenGLPFAColorSize, 24,
156         NSOpenGLPFAAlphaSize, 8,
157         NSOpenGLPFADepthSize, 24,
158         NSOpenGLPFAStencilSize, 8,
159         NSOpenGLPFAAccumSize, 0,
160         0
161     };
162
163     NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
164         initWithAttributes: (NSOpenGLPixelFormatAttribute*) attribs];
165
166     self = [super initWithFrame:frame pixelFormat: [fmt autorelease]];
167
168     if( !self )
169     {
170         return NULL;
171     }
172
173     [[self openGLContext] makeCurrentContext];
174     [self reshape];
175
176
177     glGenTextures( 2, texture );
178     truc = (uint8_t*) malloc( 1024*1024*4 );
179
180     return self;
181 }
182
183 /*
184  * Resize ourself
185  */
186 - (void) reshape
187 {
188    NSRect bounds;
189
190    [[self openGLContext] update];
191    bounds = [self bounds];
192    if( fTitle )
193    {
194        glViewport( 0, 0, fTitle->outWidthMax + 2,
195                    fTitle->outHeightMax + 2 );
196    }
197 }
198
199 - (void) drawAnimation: (int) how
200 {
201     /* Swap buffers only during the vertical retrace of the monitor.
202        http://developer.apple.com/documentation/GraphicsImaging/
203        Conceptual/OpenGL/chap5/chapter_5_section_44.html */
204     long params[] = { 1 };
205     CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,
206                      params );
207
208     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
209     glMatrixMode( GL_PROJECTION );
210     glLoadIdentity();
211     glFrustum( -1.0, 1.0, -1.0, 1.0, PROUT, 20.0 );
212     glMatrixMode( GL_MODELVIEW );
213     glLoadIdentity();
214     glTranslatef( 0.0, 0.0, translation );
215     glRotatef( rotation, 0.0, 1.0, 0.0 );
216  
217     glEnable( GL_POLYGON_SMOOTH );
218     glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
219  
220     glBindTexture( GL_TEXTURE_2D, texture[0] );
221  
222     glBegin( GL_QUADS );
223     glTexCoord2f( 0.0, 0.0 );
224     glVertex3f( -1.0, -1.0,  1.0 );
225     glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
226     glVertex3f(  1.0, -1.0,  1.0 );
227     glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
228                   ( 2.0 + fTitle->outHeightMax ) / 1024 );
229     glVertex3f(  1.0,  1.0,  1.0 );
230     glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
231     glVertex3f( -1.0,  1.0,  1.0 );
232     glEnd();
233  
234     glBindTexture( GL_TEXTURE_2D, texture[1] );
235  
236     glBegin( GL_QUADS );
237     if( how == HB_ANIMATE_RIGHT )
238     {
239         glTexCoord2f( 0.0, 0.0 );
240         glVertex3f(  1.0, -1.0,  1.0 );
241         glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
242         glVertex3f(  1.0, -1.0,  -1.0 );
243         glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
244                       ( 2.0 + fTitle->outHeightMax ) / 1024 );
245         glVertex3f(  1.0,  1.0,  -1.0 );
246         glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
247         glVertex3f(  1.0,  1.0,  1.0 );
248     }
249     else
250     {
251         glTexCoord2f( 0.0, 0.0 );
252         glVertex3f(  -1.0, -1.0, -1.0 );
253         glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024, 0.0 );
254         glVertex3f(  -1.0, -1.0, 1.0 );
255         glTexCoord2f( ( 2.0 + fTitle->outWidthMax ) / 1024,
256                       ( 2.0 + fTitle->outHeightMax ) / 1024 );
257         glVertex3f(  -1.0,  1.0, 1.0 );
258         glTexCoord2f( 0.0, ( 2.0 + fTitle->outHeightMax ) / 1024 );
259         glVertex3f(  -1.0,  1.0, -1.0 );
260     }
261     glEnd();
262  
263     [[self openGLContext] flushBuffer];
264 }
265
266 - (void) drawRect: (NSRect) rect
267 {
268    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
269
270    if( !fPicture )
271    {
272        return;
273    }
274
275    glDrawPixels( fTitle->outWidthMax + 2,
276                  fTitle->outHeightMax + 2, GL_RGBA,
277                  GL_UNSIGNED_BYTE, fPicture );
278
279    [[self openGLContext] flushBuffer];
280 }
281
282 @end