Hi Chris,
I wasn't doing the CGImageSourceCreateWithData method because i hadn't
reached that page in the docs yet :P, I am doing it like that now
though thanks. (For the purpose of others who might stumble upon this
thread in the archives : when i compiled it there was a warning about
incompatible pointer types, casting the [NSData ....] as (CFDataRef)
takes care of it).
Sure enough when I run QC under rosetta the problem I had with the
channels being mixed up came back... I found you can check the
current architecture / byte order with CFByteOrderGetCurrent() and so
now the following line works on both systems.
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, width,
height, 8, width*4, space, (CFByteOrderGetCurrent() ==
CFByteOrderLittleEndian) ? kCGImageAlphaPremultipliedLast :
kCGImageAlphaPremultipliedFirst);
I also came across the __LITTLE_ENDIAN__ macro, and preferred the
conditional compile which also seems to work fine... i'll probably
stick with this route...
#if __LITTLE_ENDIAN__
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, width,
height, 8, width*4, space, kCGImageAlphaPremultipliedLast);
#else
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, width,
height, 8, width*4, space, kCGImageAlphaPremultipliedFirst);
#endif
Regarding the QCImage etc. method... Officially there doesn't seem to
be any such thing as a QCImage or an equivalent. All that is mentioned
are the <QCPlugInOutputImageProvider> and
<QCPlugInOutputImageProvider> protocols which incoming and outgoing
images need to comply to respectively. <QCPlugInOutputImageProvider>
does have methods for binding the image directly to a texture etc.,
and directly incoming images seem to be objects that do comply to this
protocol, but when sent via a struct they do not (as you may remember
from an earlier post). but ultimately seeing as they're only protocols
I don't think they would be useful for what I want to do...
and finally, I alloc and release all the MSA_GLTextures in the enable/
disableExecution methods, so all the initting / cgl_ctx / glGenTexture
etc. does happen in the enableExecution.. I"ve tested with switching
fullscreen etc. and all is fine. It is true that the the files are
reloaded everytime you enable/disable and that part of the code can be
split into a different function - but for my purposes I think it's
fine...
Many thanks again for all your help,
Cheers,
Memo.
P.S. I've included the full updated code below for those who might be
looking for similar functionality
#import <Cocoa/Cocoa.h>
#import <OpenGL/CGLMacro.h>
@interface MSA_GLTexture : NSObject {
GLuint width, height;
GLuint myTextureName;
CGLContextObj cgl_ctx;
}
- (id)initWithImage:(NSString *)imageName andContext:
(CGLContextObj)_cgl_ctx;
- (void)render;
@end
@implementation MSA_GLTexture
- (id)initWithImage:(NSString *)imageName andContext:
(CGLContextObj)_cgl_ctx {
if(self = [super init]) {
cgl_ctx = _cgl_ctx;
NSBundle *thisBundle=[NSBundle bundleForClass:[self class]];
NSString *imagePath=[thisBundle pathForResource:imageName
ofType:nil];
CGImageSourceRef myImageSourceRef =
CGImageSourceCreateWithData((CFDataRef)[NSData
dataWithContentsOfFile:imagePath],nil);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex
(myImageSourceRef, 0, nil);
width = CGImageGetWidth(myImageRef);
height = CGImageGetHeight(myImageRef);
CGRect rect = {{0, 0}, {width, height}};
void * myData = calloc(width * 4, height);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
#if __LITTLE_ENDIAN__
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, width,
height, 8, width*4, space, kCGImageAlphaPremultipliedLast);
#else
CGContextRef myBitmapContext = CGBitmapContextCreate (myData, width,
height, 8, width*4, space, kCGImageAlphaPremultipliedFirst);
#endif
// CGContextRef myBitmapContext = CGBitmapContextCreate (myData,
width, height, 8, width*4, space, (CFByteOrderGetCurrent() ==
CFByteOrderLittleEndian) ? kCGImageAlphaPremultipliedLast :
kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(myBitmapContext, rect, myImageRef);
CGContextRelease(myBitmapContext);
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &myTextureName);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, width, height,
0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, myData);
free(myData);
}
return self;
}
-(void)render {
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTextureName);
// glEnable(GL_BLEND);
// glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, height);
glVertex3f(-0.5f, -0.5f, 0.0f);
glTexCoord2f(width, height); glVertex3f(0.5f, -0.5f,
0.0f);
glTexCoord2f(width, 0.0f);
glVertex3f(0.5f, 0.5f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.0f);
glEnd();
glDisable(GL_TEXTURE_RECTANGLE_ARB);
}
@end
Memo (Mehmet S. Akten)
www.memo.tv
[EMAIL PROTECTED]
+44 (0) 7958 783 832
+44 (0) 20 8123 9986
29 Ironworks
Dace Rd
London E3 2NX, UK
On 8 Jun 2008, at 14:13, Christopher Wright wrote:
"but now I'm having another problem (sigh), i'm loading an image
with alpha, and its almost correct, but its appearing a bit
seethrough and the colors a bit off. I'm guessing it might have to
do with the byte order set in glPixelStore or glTextImage2D etc....
but I couldn't find a solution. I'm also a bit wary of whether or
not it it will behave differently on intel vs powerpc - i.e. I'd
like it to be failsafe and generic (checking the system etc.)
instead of just trial and error working on my machine.... I've
included the core of the code below (minus other stuff for
position, scale etc.), it's for a class which (is supposed to) just
take care of loading a file and rendering it"
I actually just found a solution to this problem - changing
kCGImageAlphaPremultipliedFirst to kCGImageAlphaPremultipliedLast
in the CGBitmapContextCreate works for me - but I'm not sure if
this is hackish solution for this file or my machine, or whether
thats how it should be fullstop regardless of file format and/or
architexture.. I"m reading through the Quartz Programming Guide,
but it is 224 pages and if anyone knows the answer would be much
appreciated :P ...
Can't you create/use a QCImage (or the official-api equivalent)
without needing to fight with glTexImage2D? I'm thinking that'll
handle different archs and weird things like this transparently,
plus any other weird problems you'd run into. But maybe the api
doesn't support this...
Also: setting cgl_ctx in the init function may be incomplete. If
the user stops rendering and changes the context (i.e. switches to
fullscreen/new view in an app etc), the input context can change
without calling init again. You might want to set cgl_ctx in the
enable function (or StartRendering or whatever the equiv. is again)
to ensure that you get updates when those changes happen.
Rather than doing URL handwaving to load your image, why not just
load from data? :
NSBundle *thisBundle=[NSBundle bundleForClass:[self class]];
NSString *imagePath=[thisBundle pathForResource:imageName
ofType:nil];
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)
imagePath, kCFURLPOSIXPathStyle, 0);
CGImageSourceRef myImageSourceRef =
CGImageSourceCreateWithURL(url, nil);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex
(myImageSourceRef, 0, nil);
becomes something like
NSBundle *thisBundle=[NSBundle bundleForClass:[self class]];
NSString *imagePath=[thisBundle pathForResource:imageName
ofType:nil];
CGImageSourceRef myImageSourceRef =
CGImageSourceCreateWithData([NSData
dataWithContentsOfFile:imagePath],nil);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex
(myImageSourceRef, 0, nil);
When you use glGenTexture, you'll also want to do that in the enable
function (when contexts change), since the textures/vbos/whatever
you're using are only valid while the context is.
To test on PPC with an intel mac, Get Info on the Quartz
Composer.app bundle (right click -> Get Info, or cmd-I), and check
the "Open Using Rosetta" check box. Make sure to uncheck it when
you need optimal performance. :) This is handy for testing
potential endian issues.
<RosettaMode.jpg>
--
[ christopher wright ]
[EMAIL PROTECTED]
http://kineme.net/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]