root/oggzcap/src/SampleCIView.m

Revision 0a70e0d806f25ff621a815590d0f3de9d88a1926, 5.5 kB (checked in by Robin Gareus <robin@…>, 3 years ago)

added OggZCapture OSX App.

  • Property mode set to 100755
Line 
1
2#import "SampleCIView.h"
3
4#import <OpenGL/OpenGL.h>
5#import <OpenGL/gl.h>
6
7static CGRect centerSizeWithinRect(CGSize size, CGRect rect);
8
9@implementation SampleCIView
10
11+ (NSOpenGLPixelFormat *)defaultPixelFormat
12{
13    static NSOpenGLPixelFormat *pf;
14
15    if (pf == nil)
16    {
17        /* Making sure the context's pixel format doesn't have a recovery
18         * renderer is important - otherwise CoreImage may not be able to
19         * create deeper context's that share textures with this one. */
20
21        static const NSOpenGLPixelFormatAttribute attr[] = {
22            NSOpenGLPFAAccelerated,
23            NSOpenGLPFANoRecovery,
24            NSOpenGLPFAColorSize,
25                (NSOpenGLPixelFormatAttribute)32,
26            (NSOpenGLPixelFormatAttribute)0
27        };
28
29        pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*)&attr];
30    }
31
32    return pf;
33}
34
35- (void)dealloc
36{
37        //NSLog(@"[SampleCIView dealloc]");
38    [_image release];
39    [_context release];
40
41    [super dealloc];
42}
43
44- (CIImage*)image
45{
46    return [[_image retain] autorelease];
47}
48
49- (void)setImage:(CIImage*)image dirtyRect:(CGRect)r
50{
51    if (_image != image)
52    {
53        [_image release];
54        _image = [image retain];
55
56        if (CGRectIsInfinite (r))
57            [self setNeedsDisplay:YES];
58        else
59            [self setNeedsDisplayInRect:*(NSRect *)&r];
60    }
61}
62
63- (void)setImage:(CIImage*)image
64{
65    [self setImage:image dirtyRect:CGRectInfinite];
66}
67
68- (void)setCleanRect:(CGRect)cleanRect
69{
70        _cleanRect = cleanRect;
71}
72
73- (void)setDisplaySize:(CGSize)displaySize
74{
75        _displaySize = displaySize;
76}
77
78- (void)prepareOpenGL
79{
80    long parm = 1;
81
82    /* Enable beam-synced updates. */
83
84    [[self openGLContext] setValues:&parm forParameter:NSOpenGLCPSwapInterval];
85
86    /* Make sure that everything we don't need is disabled. Some of these
87     * are enabled by default and can slow down rendering. */
88
89    glDisable (GL_ALPHA_TEST);
90    glDisable (GL_DEPTH_TEST);
91    glDisable (GL_SCISSOR_TEST);
92    glDisable (GL_BLEND);
93    glDisable (GL_DITHER);
94    glDisable (GL_CULL_FACE);
95    glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
96    glDepthMask (GL_FALSE);
97    glStencilMask (0);
98    glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
99    glHint (GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
100}
101
102- (void)viewBoundsDidChange:(NSRect)bounds
103{
104#pragma unused(bounds)
105    /* For subclasses. */
106}
107
108- (void)updateMatrices
109{
110    NSRect r = [self bounds];
111
112    if (!NSEqualRects (r, _lastBounds))
113    {
114        [[self openGLContext] update];
115
116        /* Install an orthographic projection matrix (no perspective)
117         * with the origin in the bottom left and one unit equal to one
118         * device pixel. */
119
120        glViewport (0, 0, r.size.width, r.size.height);
121
122        glMatrixMode (GL_PROJECTION);
123        glLoadIdentity ();
124        glOrtho (0, r.size.width, 0, r.size.height, -1, 1);
125
126        glMatrixMode (GL_MODELVIEW);
127        glLoadIdentity ();
128
129        _lastBounds = r;
130
131        [self viewBoundsDidChange:r];
132    }
133}
134
135- (void)drawRect:(NSRect)r
136{
137    CGRect ir, rr;
138    CGImageRef cgImage;
139
140    [[self openGLContext] makeCurrentContext];
141
142    /* Allocate a CoreImage rendering context using the view's OpenGL
143     * context as its destination if none already exists. */
144
145    if (_context == nil)
146    {
147        NSOpenGLPixelFormat *pf;
148
149        pf = [self pixelFormat];
150        if (pf == nil)
151            pf = [[self class] defaultPixelFormat];
152
153        _context = [[CIContext contextWithCGLContext:CGLGetCurrentContext() pixelFormat:[pf CGLPixelFormatObj] options:nil] retain];
154    }
155
156    ir = CGRectIntegral (*(CGRect *)&r);
157
158    if ([NSGraphicsContext currentContextDrawingToScreen])
159    {
160        [self updateMatrices];
161
162        /* Clear the specified subrect of the OpenGL surface then
163         * render the image into the view. Use the GL scissor test to
164         * clip to * the subrect. Ask CoreImage to generate an extra
165         * pixel in case * it has to interpolate (allow for hardware
166         * inaccuracies) */
167
168        rr = CGRectIntersection (CGRectInset (ir, -1.0f, -1.0f),
169                                 *(CGRect *)&_lastBounds);
170
171        glScissor (ir.origin.x, ir.origin.y, ir.size.width, ir.size.height);
172        glEnable (GL_SCISSOR_TEST);
173
174        glClear (GL_COLOR_BUFFER_BIT);
175
176        if ([self respondsToSelector:@selector (drawRect:inCIContext:)])
177        {
178            [self drawRect:*(NSRect *)&rr inCIContext:_context];
179        }
180        else if (_image != nil)
181        {
182                // use the commented out method if you don't want to perform scaling
183            //[_context drawImage:_image atPoint:rr.origin fromRect:rr];
184                CGRect where = centerSizeWithinRect(_displaySize, *(CGRect *)&_lastBounds);
185                [_context drawImage:_image inRect:where fromRect:_cleanRect];
186        }
187       
188        glDisable (GL_SCISSOR_TEST);
189
190        /* Flush the OpenGL command stream. If the view is double
191         * buffered this should be replaced by [[self openGLContext]
192         * flushBuffer]. */
193
194        glFlush ();
195        //[[self openGLContext] flushBuffer] ;
196       
197    }
198    else
199    {
200        /* Printing the view contents. Render using CG, not OpenGL. */
201
202        if ([self respondsToSelector:@selector (drawRect:inCIContext:)])
203        {
204            [self drawRect:*(NSRect *)&ir inCIContext:_context];
205        }
206        else if (_image != nil)
207        {
208            cgImage = [_context createCGImage:_image fromRect:ir];
209
210            if (cgImage != NULL)
211            {
212                CGContextDrawImage ([[NSGraphicsContext currentContext] graphicsPort], ir, cgImage);
213                CGImageRelease (cgImage);
214            }
215        }
216    }
217}
218
219@end
220
221static CGRect centerSizeWithinRect(CGSize size, CGRect rect)
222{
223        float delta;
224        if( CGRectGetHeight(rect) / CGRectGetWidth(rect) > size.height / size.width ) {
225                // rect is taller: fit width
226                delta = rect.size.height - size.height * CGRectGetWidth(rect) / size.width;
227                rect.size.height -= delta;
228                rect.origin.y += delta/2;
229        }
230        else {
231                // rect is wider: fit height
232                delta = rect.size.width - size.width * CGRectGetHeight(rect) / size.height;
233                rect.size.width -= delta;
234                rect.origin.x += delta/2;
235        }
236        return rect;
237}
Note: See TracBrowser for help on using the browser.