Re: NSCopyBits
Re: NSCopyBits
- Subject: Re: NSCopyBits
- From: Andrew Frezell <email@hidden>
- Date: Mon, 31 Mar 2003 17:54:04 -0500
> You probably want to get you view, named say...myView
> and lockFocus on it before calling NSCopyBits.
>
> [myView lockFocus];
>
> lockFocus is supposed to make the NSView's graphic state the current
> one.
>
> This way you should be able to call NSCopyBits with a NSNullObject, to
> use the
> current graphic state to draw into. (Or says the docs)
>
> you can then call unlockFocus to revert to the previous graphic state.
> [myView unlockFocus];
I currently do this. I was being a bit brief in what I'm doing so not
to have a long message, but I will elaborate. I'm currently working on
porting XScreenSaver to use the ScreenSaver framework provided. At
first I was rewriting each screen saver and the supporting functions to
Cocoa, then I decided to work on writing a basic portability layer for
Xlib functions using OpenGL/Cocoa, the problem I've found is
implementing the XCopyArea function...it seems NSCopyBits should do
just this, but I don't see the expected results so I'm thinking it may
be because I'm not updating the view after the NSCopyBits...I would
normally think this would happen immediately, and not require an
explicit call to cause a repaint...but, seeing how there is very little
information on NSCopyBits, I was hoping to find out what actually
happens when calling NSCopyBits. Anyways, here is the code for using
the OpenGL view in XScreenSaver...maybe this will help in detecting
what I'm doing wrong.
NOTE: The below code may not compile straight out of the box, I only
pasted the meat of the screensaver code to give everyone an idea of
what I'm doing. If you would like, I can email fully compiling code to
test this.
//============================================
// OpenGLView.m
//============================================
@implementation OpenGLView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[self openGLContext] makeCurrentContext];
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
return self;
}
- (void)drawRect:(NSRect)rect {
NSView *superview = [self superview];
[superview lockFocus];
[superview drawRect:rect];
[superview unlockFocus];
}
- (void)setFrameSize:(NSSize)newSize {
[super setFrameSize:newSize];
[[self openGLContext] makeCurrentContext];
glViewport(0, 0, newSize.width, newSize.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, newSize.width, 0, newSize.height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
@end
//============================================
// TestView.h
//============================================
@interface TestView : ScreenSaverView {
OpenGLView *m_glView;
}
@end
//============================================
// TestView.m
//============================================
@implementation TestView
- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
self = [super initWithFrame:frame isPreview:isPreview];
if (self) {
m_glView = [[OpenGLView alloc] initWithFrame:NSZeroRect
pixelFormat:nil];
if (!m_glView) {
[self autorelease];
return nil;
}
[self addSubview:m_glView];
[m_glView release];
[self setAnimationTimeInterval:1/30.0];
}
return self;
}
- (void)startAnimation
{
[super startAnimation];
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
- (void)stopAnimation
{
[super stopAnimation];
}
- (void)setFrameSize:(NSSize)newSize
{
[super setFrameSize:newSize];
[m_glView setFrameSize:newSize];
}
- (void)drawRect:(NSRect)rect
{
int i, j, x, y;
int width = NSWidth(rect);
int height = NSHeight(rect);
[super drawRect:rect];
[Erase eraseFullWindowWidth: NSWidth(rect)
windowHeight:NSHeight(rect)];
glColor3ub(SSRandomIntBetween(0, 255), SSRandomIntBetween(0, 255),
SSRandomIntBetween(0, 255));
int rand = SSRandomIntBetween(0, 20);
for (i = 0; i < width; i++) {
for (j = 0; j < height; j++) {
x = (i * i + j * j) % width;
y = (i * j + j * i) % height;
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
glFlush();
}
}
- (void)animateOneFrame
{
[self setNeedsDisplay:YES];
return;
}
- (BOOL)hasConfigureSheet
{
return NO;
}
- (NSWindow*)configureSheet
{
return nil;
}
@end
//============================================
// Erase.m
// The Xlib port layer I want
//============================================
#undef countof
#define countof(x) (sizeof(x)/sizeof(*(x)))
#define LITTLE_NAP 5000 /* 1/200th sec */
#define Display int
#define Window int
#define Drawable int
#define GC int
#define Bool BOOL
#define False 0
#define True 1
static unsigned long millitime(void) {
struct timeval tt;
struct timezone tz;
gettimeofday (&tt, &tz);
return (tt.tv_sec * 1000) + (tt.tv_usec / 1000);
}
typedef struct {
short x, y;
} XPoint;
static void XFillRectangle(Display *d, Window w, GC g, int x, int y,
unsigned int width, unsigned int height) {
glBegin(GL_QUADS);
glVertex2i(x, y);
glVertex2i(x + width, y);
glVertex2i(x + width, y + height);
glVertex2i(x, y + height);
glEnd();
}
static void XCopyArea(Display *d, Drawable src, Drawable dest, GC g,
int src_x, int src_y, unsigned int width, unsigned int height,
int dest_x, int dest_y) {
NSRect mysrc = NSMakeRect(src_x, src_y, width, height);
NSPoint mydest;
dest.x = dest_x;
dest.y = dest_y;
NSCopyBits(nil, mysrc, mydest);
}
static void XSync(Display *d, int discard) {
glFlush();
}
/* I first saw something like this, albeit in reverse, in an early
Tetris
implementation for the Mac.
-- Torbjrn Andersson <email@hidden>
*/
static void
slide_lines (Display *dpy, Window window, GC gc,
int width, int height, int total_msecs)
{
int max = width;
int dy = MAX (10, height/40);
int oi = 0;
unsigned long start_tick = millitime();
unsigned long end_tick = start_tick + total_msecs;
unsigned long tick = start_tick;
int hits = 0;
int nonhits = 0;
while (tick < end_tick)
{
int i = (max * (tick - start_tick)) / (end_tick - start_tick);
if (i == oi)
{
usleep (LITTLE_NAP);
nonhits++;
}
else
{
int y;
int tick = 0;
int from1 = oi;
int to1 = i;
int w = width-to1;
int from2 = width - oi - w;
int to2 = width - i - w;
for (y = 0; y < height; y += dy)
{
if (++tick & 1)
{
XCopyArea (dpy, window, window, gc, from1, y, w, dy,
to1, y);
XFillRectangle (dpy, window, gc, from1, y, to1-from1,
dy);
}
else
{
XCopyArea (dpy, window, window, gc, from2, y, w, dy,
to2, y);
XFillRectangle (dpy, window, gc, from2+w, y,
to2-from2, dy);
}
}
hits++;
XSync (dpy, False);
}
oi = i;
tick = millitime();
}
}
@implementation Erase
+ (void)eraseFullWindowWidth: (int)width windowHeight: (int)height {
int erase_msecs = 2000;
glColor3ub(0, 0, 0);
slide_lines(0, 0, 0, width, height, erase_msecs);
usleep(333333); /* 1/3 sec */
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.