OSDN Git Service

first commit
[eliscolors/main.git] / ElisMainView.m
1 //
2 //  ElisMainView.m
3 //  Elis Colors
4 //
5 //  Created by 柳 on 09/09/12.
6 //  Copyright 2009 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ElisMainView.h"
10
11 #pragma mark Render Callback
12 static CVReturn MyRenderCallback(CVDisplayLinkRef displayLink, 
13                                                                  const CVTimeStamp *inNow, 
14                                                                  const CVTimeStamp *inOutputTime, 
15                                                                  CVOptionFlags flagsIn, 
16                                                                  CVOptionFlags *flagsOut, 
17                                  void *displayLinkContext)
18 {
19         return [(ElisMainView *)displayLinkContext getFrameForTime:inOutputTime flagsOut:flagsOut];
20 }
21
22 @implementation ElisMainView
23
24 - (void)awakeFromNib
25 {
26     mainView = self;
27     lock = [[NSRecursiveLock alloc] init];
28     timeOffset = QTZeroTime;
29 //    layerSet = malloc(sizeof(void*) * TRACK_SIZE);
30     layerSet = [[NSMutableArray alloc] init];
31     sortedLayerSet = malloc(sizeof(void*) * TRACK_SIZE);
32 }
33
34 - (void)prepareOpenGL
35 {
36     NSLog(@"Initializing OpenGL ...");
37         GLint swapInterval = 1;
38     
39     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);   // black background
40         [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
41     
42     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
43     ciContext = [CIContext contextWithCGLContext:[[self openGLContext] CGLContextObj]
44                                       pixelFormat:[[self pixelFormat] CGLPixelFormatObj]
45                                           options:[NSDictionary dictionaryWithObjectsAndKeys:(id)colorSpace, kCIContextOutputColorSpace,
46                                                    (id)colorSpace, kCIContextWorkingColorSpace, nil]];
47     
48     CGColorSpaceRelease(colorSpace);
49     
50     CVDisplayLinkCreateWithCGDisplay(kCGDirectMainDisplay, &displayLink);
51     if (NULL != displayLink) {
52         CVDisplayLinkSetCurrentCGDisplay(displayLink, kCGDirectMainDisplay);
53         CVDisplayLinkSetOutputCallback(displayLink, &MyRenderCallback, self);
54     }
55     
56     NSLog(@"Elis Colors, Stand by ready.");
57 }
58
59 #pragma mark Display Link
60 - (CVReturn)getFrameForTime:(CVTimeStamp*)timeStamp flagsOut:(CVOptionFlags*)flagsOut
61 {
62     [lock lock];
63     QTTime qt;
64     NSDate* now;
65     NSTimeInterval duration;
66     now = [[NSDate alloc] init];
67     duration = [now timeIntervalSinceDate:startTime]; // 再生を開始した時間と今の時間から経過時間を得る。
68     qt = QTMakeTime(duration*600, 600); // 経過時間をQTTimeに変換。
69     _qt = QTTimeIncrement(qt, timeOffset); // オフセットを足す。
70     
71     stamp = timeStamp;
72 //    
73     [layerSet removeAllObjects];
74     [_mainController getFrameForTime:_qt result:layerSet];
75 //    [now release];
76     [self drawRect:NSZeroRect];
77     [lock unlock];
78     return kCVReturnSuccess;
79 }
80
81 - (void)getFrameForQTTime:(QTTime)time
82 {
83     [lock lock];
84     [layerSet removeAllObjects];
85     [_mainController getFrameForTime:time result:layerSet];
86     [self drawRectWithoutStamp:NSZeroRect forTime:time];
87     [lock unlock];
88 }
89
90 - (void)drawRectWithoutStamp:(NSRect)rect forTime:(QTTime)time
91 {
92     [lock lock];
93     
94     [[self openGLContext] makeCurrentContext];
95     glClear(GL_COLOR_BUFFER_BIT);
96     
97     int i, size = [layerSet count];
98     CIImage* ci;
99     NSPoint point;
100     CGRect imageRect;
101     CGPoint cp;
102     
103     // トラック番号順にバケットソート
104     memset(sortedLayerSet, 0, sizeof(void*) * TRACK_SIZE);
105     for(i = 0; i < size; i++)
106         sortedLayerSet[[[layerSet objectAtIndex:i] trackNumber]] = [layerSet objectAtIndex:i];
107     
108     for(i = 0; i < TRACK_SIZE; i++){
109         if(sortedLayerSet[i] == 0) continue;
110         
111         ci = [sortedLayerSet[i] getEffectedImageWithoutStamp:time]; // 違いはここ。
112         point = [sortedLayerSet[i] getPositionForTime:[sortedLayerSet[i] convertToInnnerTime:time]];
113         if(ci == nil) continue; // サウンドレイヤーはスキップ
114         imageRect = [ci extent];
115         if(imageRect.size.width >= 4000){
116             imageRect = CGRectMake(0.0, 0.0, 4000, 3000);
117         }
118         
119         cp = *(CGPoint*)&point;
120 //        [ciContext drawImage:ci inRect:CGRectMake(point.x, point.y, imageRect.size.width, imageRect.size.height) fromRect:imageRect];
121         [ciContext drawImage:ci atPoint:cp fromRect:imageRect];        
122 //        [ciContext drawImage:ci inRect:CGRectMake(point.x, point.y, 640, 480) fromRect:CGRectMake(0, 0, 640, 480)];
123     }
124     
125     glFlush();
126     
127     // あとかたづけ
128     for(i = 0; i < size; i++)
129         [[layerSet objectAtIndex:i] releaseContext];
130     
131     [layerSet removeAllObjects];
132
133     [lock unlock];
134 }
135
136 - (void)drawRect:(NSRect)rect
137 {
138     [lock lock];
139     
140     [[self openGLContext] makeCurrentContext];
141     glClear(GL_COLOR_BUFFER_BIT);
142
143     int i, size = [layerSet count];
144     CIImage* ci;
145     NSPoint point;
146     CGRect imageRect;
147     CGPoint cp;
148     
149     // トラック番号順にバケットソート
150     memset(sortedLayerSet, 0, sizeof(void*) * TRACK_SIZE);
151     for(i = 0; i < size; i++)
152         sortedLayerSet[[[layerSet objectAtIndex:i] trackNumber]] = [layerSet objectAtIndex:i];
153
154     for(i = 0; i < TRACK_SIZE; i++){
155         if(sortedLayerSet[i] == 0) continue;
156         
157         ci = [sortedLayerSet[i] getEffectedImage:stamp forTime:_qt];
158         point = [sortedLayerSet[i] getPositionForTime:[sortedLayerSet[i] convertToInnnerTime:_qt]];
159         if(ci == nil) continue; // サウンドレイヤーはスキップ
160         
161         imageRect = [ci extent];
162         if(imageRect.size.width >= 4000){
163             imageRect = CGRectMake(0, 0, 4000, 3000);
164         }
165
166         cp = *(CGPoint*)&point;
167 //        [ciContext drawImage:ci inRect:imageRect fromRect:CGRectMake(point.x, point.y, ProjectMovieSize.size.width, ProjectMovieSize.size.height)];
168         [ciContext drawImage:ci atPoint:cp fromRect:imageRect];
169 //        [ciContext drawImage:ci inRect:CGRectMake(point.x, point.y, imageRect.size.width, imageRect.size.height)
170 //                    fromRect:imageRect];
171     }
172     
173     // あとかたづけ
174     for(i = 0; i < size; i++)
175         [[layerSet objectAtIndex:i] releaseContext];
176     
177     [layerSet removeAllObjects];
178     
179  //   int size = [imageSet count], i;
180 //    NSPoint np;
181 //    CIImage* ci;
182 //    CGRect imRect;
183 //    for(i = 0; i < size; i += 2){
184 //        ci = [imageSet objectAtIndex:i];
185 //        np = [[imageSet objectAtIndex:i+1] pointValue];
186 //        imRect = [ci extent];
187 //        
188 //        if(imRect.size.width >= 4096.0)
189 //            imRect = CGRectMake(0, 0, 640, 480);
190 //        [ciContext drawImage:ci inRect:imRect//CGRectMake(np.x, np.y, 640, 480) 
191 //                    fromRect:CGRectMake(np.x, np.y, 640, 480)];
192 //    }
193     glFlush();
194     
195 //    size = [contexts count];
196 //    for(i = 0; i < size; i++)
197 //        QTVisualContextTask([contexts objectAtIndex:i]);
198 //    
199 //    [imageSet release];
200 //    imageSet = nil;
201     [lock unlock];
202 }
203
204 - (void)reshape
205
206         GLfloat minX, minY, maxX, maxY;
207     
208     NSRect sceneBounds = [self bounds];
209         NSRect frame = [self frame];
210         
211     minX = NSMinX(sceneBounds);
212         minY = NSMinY(sceneBounds);
213         maxX = NSMaxX(sceneBounds);
214         maxY = NSMaxY(sceneBounds);
215     
216     glViewport(0, 0, (GLsizei)frame.size.width, (GLsizei)frame.size.height);    // set the viewport
217     
218     glMatrixMode(GL_MODELVIEW);    // select the modelview matrix
219     glLoadIdentity();              // reset it
220     
221     glMatrixMode(GL_PROJECTION);   // select the projection matrix
222     glLoadIdentity();              // reset it
223     
224     gluOrtho2D(minX, maxX, minY, maxY); // define a 2-D orthographic projection matrix
225     
226         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
227     glEnable(GL_BLEND);
228 }
229
230 - (void)stopDisplayLink
231 {
232     [startTime release];
233     startTime = nil;
234     CVDisplayLinkStop(displayLink);
235 }
236
237 - (void)startDisplayLink
238 {
239     startTime = [[NSDate alloc] init];
240     CVDisplayLinkStart(displayLink);
241 }
242
243 - (void)seek:(QTTime)time
244 {
245     timeOffset = time;
246 }
247
248 - (void)getCurrentPixelData:(NSRect)rect buffer:(unsigned char*)buffer
249 {
250     glReadBuffer(GL_FRONT); // フロントバッファ(って何だろう?)からピクセルを読みに行く。
251     glReadPixels(0, 0, rect.size.width, rect.size.height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
252 }
253
254 @end