I've had a bug in some GL code for about an hour, and I've been beating my head against the wall trying to figure out what I'd done wrong. glGetUniformLocation was returning crazy values, and glUniform1f was generating an invaild operation. The problem? glUniform1f where I had intended glUniform1i. A simple typo, but somehow it also screwed up the values coming back from glGetUniformLocation, which is where I noticed it.
On that note, remember that glUniform* act on the currently bound program, so make sure there is one before you call it.
Thursday, March 27, 2008
Sunday, March 23, 2008
NSArray indexOfObjectIdentialTo:
NSArray's indexOfObjectIdenticalTo: does not behave as documented, and the the sample code given by Apple demonstrating it does not do what it says it does. For a more complete description see my two posts at:
http://www.idevapps.com/forum/showthread.php?t=6463
http://www.idevapps.com/forum/showthread.php?t=6463
Tuesday, March 18, 2008
Another Demo Finished
Up to fixing up the user controls, I've finished my reflection/refraction demo. I've used hdr textures, but I haven't tone mapped them, so they're a bit bright. I'm going to do that in a future demo. At some point I'm going to turn these into a set of tutorials, but I might wait until OpenGL 3.0 finally arrives.
ImageIO OpenGL and Radiance .hdr Files
I promised to post my ImageIO code once I had things working, and now that it's working, I'm going to do just that. I just worked through the last bug I had in my texturing code.
If you're using ImageIO to read Radiance .hdr files, and you're getting garbage, check the type parameter you're passing to glTexImage2D. The Apple documentation concerning ImageIO and OpenGL uses the format GL_UNSIGNED_INT_8_8_8_8_REV. While .hdr files are floating point, its the REV you should take note of. The byte ordering of each R, G, B component is individually reversed between what ImageIO provides and OpenGL expects. Simply call glPixelStorei(GL_UNPACK_SWAP_BYTES,1) and things should look a bit more normal.
I hope this saves someone else a few minutes.
Boolean osx_CGImageSupportsFileFormat(std::string format) {
CFArrayRef imageFormats = CGImageSourceCopyTypeIdentifiers();
CFStringRef targetImageFormat = CFStringCreateWithCString( kCFAllocatorDefault, format.c_str(), kCFStringEncodingUTF8 );
CFRange imageFormatsRange = CFRangeMake( 0, CFArrayGetCount( imageFormats ) );
Boolean didContainFormat = CFArrayContainsValue(imageFormats, CFRangeMake(0, CFArrayGetCount(imageFormats)), targetImageFormat);
CFRelease(targetImageFormat);
CFRelease(imageFormats);
return didContainFormat;
}
CGImageRef osx_CGImageCreateFromFile(std::string filename) {
CGImageRef image = 0;
CFStringRef fileString = 0;
CFURLRef fileURL = 0;
CGImageSourceRef imageSource = 0;
CFDictionaryRef imageSourceOptions = 0;
CFStringRef imageSourceKeys[] = { kCGImageSourceShouldAllowFloat, kCGImageSourceShouldCache };
CFBooleanRef imageSourceValues[] = { kCFBooleanTrue, kCFBooleanTrue };
try {
fileString = CFStringCreateWithCString( kCFAllocatorDefault, filename.c_str(), kCFStringEncodingUTF8 );
if (fileString == 0) throw std::runtime_error("CFStringCreateWithCString");
fileURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, fileString, kCFURLPOSIXPathStyle, 0);
if (fileURL == 0) throw std::runtime_error("CFURLCreateWithFileSystemPath");
imageSource = CGImageSourceCreateWithURL(fileURL, 0);
if (imageSource == 0) throw std::runtime_error("CGImageSourceCreateWithURL");
imageSourceOptions = CFDictionaryCreate( kCFAllocatorDefault, (const void**)&imageSourceKeys, (const void**)&imageSourceValues, 1, 0, 0 );
if (imageSourceOptions == 0) throw std::runtime_error("CFDictionaryCreate");
image = CGImageSourceCreateImageAtIndex(imageSource, 0, imageSourceOptions);
if (image == 0) throw std::runtime_error("CGImageSourceCreateImageAtIndex");
}
catch(std::runtime_error &problem) {
std::cerr << problem.what() << std::endl;
}
CFRelease(imageSourceOptions);
CFRelease(imageSource);
CFRelease(fileURL);
CFRelease(fileString);
return image;
}
void osx_CGImageCrossCubeToImageCube(CGImageRef source, ImageCube &imageCube) {
size_t x = CGImageGetWidth(source) / 3;
size_t y = CGImageGetHeight(source) / 4;
assert( x == y ); // Images should be square. Could scale to ensure this instead of aborting.
CGRect imageBounds[6] = {0};
imageBounds[0] = CGRectMake(2*x, y, x, y); // +x 1
imageBounds[1] = CGRectMake(0, y, x, y); // -x 0
imageBounds[2] = CGRectMake(x, 2*y, x, y); // -y 2
imageBounds[3] = CGRectMake(x, 0, x, y); // +y 3
imageBounds[4] = CGRectMake(x, y, x, y); // -z 4
imageBounds[5] = CGRectMake(x, 3*y, x, y); // +z 5
imageCube.size = x;
imageCube.bitsPerComponent = CGImageGetBitsPerComponent(source);
imageCube.numComponents = 4;
const size_t bytesPerRow = imageCube.size * imageCube.numComponents * imageCube.bitsPerComponent / 8;
CGImageRef partitions[6] = {0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
for (int i = 0; i < 6; ++i) {
imageCube.image[i].resize( imageCube.size * bytesPerRow );
partitions[i] = CGImageCreateWithImageInRect(source, imageBounds[i]);
CGContextRef imageContext = CGBitmapContextCreate( &imageCube.image[i][0],
imageCube.size, imageCube.size,
imageCube.bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaNoneSkipLast | kCGBitmapFloatComponents );
CGContextSaveGState(imageContext);
// Up Down and Backwards are flipped in the cube cross format
if ( i == 2 || i == 3 || i == 5 ) {
CGContextTranslateCTM(imageContext, imageCube.size, imageCube.size);
CGContextScaleCTM(imageContext, -1.0f, -1.0f);
}
CGContextDrawImage(imageContext, CGRectMake(0, 0, imageCube.size, imageCube.size), partitions[i]);
CGContextRestoreGState(imageContext);
CGContextRelease(imageContext);
CGImageRelease(partitions[i]);
}
CGColorSpaceRelease(colorSpace);
}
Apple and OpenGL 3.0
OS X has never had good OpenGL drivers, by which I mean few bugs, and wide support of current standards. Things have improved over time, but there are clearly still problems.
OpenGL 3.0 promises to clean up and slim down the specification, making it clearer and easier to develop and maintain a standards compliant implementation. I'm holding out hope that the change will help Apple out and the quality of their GL drivers will improve.
Speaking of OpenGL 3.0, I'm hoping that GLSL is being moved out of core, and/or that it's being replaced with something better, namely Cg; I'm tired of dealing with vendor-dependent GLSL bugs.
OpenGL 3.0 promises to clean up and slim down the specification, making it clearer and easier to develop and maintain a standards compliant implementation. I'm holding out hope that the change will help Apple out and the quality of their GL drivers will improve.
Speaking of OpenGL 3.0, I'm hoping that GLSL is being moved out of core, and/or that it's being replaced with something better, namely Cg; I'm tired of dealing with vendor-dependent GLSL bugs.
Cube Mapping
The GLSL mat3 constructor that is supposed to take a mat4 and slice out the upper 3x3 doesn't work on my MacBook Pro. Apparently I'm not the only one. http://emergencyexit.untergrund.net/2007/12/glsl/
As described in the above url, you can use the following instead:
As described in the above url, you can use the following instead:
mat3(matrix[0].xyz, matrix[1].xyz, matrix[2].xyz)
Sunday, March 16, 2008
CGImage Problems
I'm trying to use ImageIO to load Radiance HDR files, then draw the contents to a user-backed floating point context, but things are crashing. Once I figure out what's wrong, I'll post code.
Andrew.
Andrew.
Tuesday, March 11, 2008
OpenGL Demos
I've written an implementation of Preetham's "A Practical Analytic Model for Daylight", an ambient occlusion demo, a vertex buffer object demo, and a GLSL per-pixel lighting demo, I'll post them soon. Tomorrow I'm going to start on a reflection/refraction demo. I'll likely follow them up with a set of tutorials explaining them in some detail; I'd like to start doing more tutorials.
Saturday, March 8, 2008
New Macbook Pro
I'd had enough of OpenGL driver problems on my old mac, so today I went out and picked up a new one. I grabbed a new 2.5Ghz, which has an 8600GM 512M card, which should outpace my G4 17" by quite a bit. I'm eager to start using the new gesture controls in my programs.
Thursday, March 6, 2008
gl_NormalMatrix
I've run into a few driver problems under OS X
For comparison, here are my system specs:
Mac OS X Version 10.5.2
Processor: 1.5 GHz PowerPC G4
Memory 512 MB DDR SDRAM
gl_NormalMatrix is computed incorrectly on my mac.
The problem, and a temporary solution are listed below.
Framebuffer objects must be powers of two.
More to come.
For comparison, here are my system specs:
Mac OS X Version 10.5.2
Processor: 1.5 GHz PowerPC G4
Memory 512 MB DDR SDRAM
gl_NormalMatrix is computed incorrectly on my mac.
The problem, and a temporary solution are listed below.
frag_Normal = gl_NormalMatrix * gl_Normal
frag_Normal = (gl_ModelViewMatrix * vec4(gl_Normal, 0.0)).xyz
Framebuffer objects must be powers of two.
More to come.
Wednesday, March 5, 2008
Revisiting Shadow Mapping
Subscribe to:
Posts (Atom)