OpenGL drawing problems on older iMac's
I created app witch acts like drawing app. User opens photo and then can draw on it with brush tool (mouseDown ad mouseDragged). Drawing is handled by OpenGL. Everything works like that:
- User opens Image
- Image is being processed to be used as OpenGL texture :
_source = CGImageSourceCreateWithData((__bridge CFDataRef)[_created_nsimage TIFFRepresentation], NULL);
_cgimage = CGImageSourceCreateImageAtIndex(_source, 0, NULL);
_cg_image_width = CGImageGetWidth(_cgimage);
_cg_image_height = CGImageGetHeight(_cgimage);
_image_data = (GLubyte *) calloc(_cg_image_width * _cg_image_height * 4, sizeof(GLubyte));
_context = CGBitmapContextCreate(_image_data, _cg_image_width, _cg_image_height, 8, _cg_image_width * 4, CGImageGetColorSpace(_cgimage), kCGImageAlphaPremultipliedLast);
CGContextDrawImage(_context, CGRectMake(0.0, 0.0, (CGFloat)_cg_image_width, (CGFloat)_cg_image_height), _cgimage);
CGContextRelease(_context);
OpenGL texture is created. While creating texture these parameters are used:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Image is added to OpenGL texture like that:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)_cg_image_width , (int)_cg_image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, _glubyte_storage);
App creates _image_framebuffer, _brush_framebuffer and _main_framebuffer then, like that:
glGenTextures(1, &_image_framebuffer_texture);
glBindTexture(GL_TEXTURE_2D, &_image_framebuffer_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glGenerateMipmap(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _cg_image_width, _cg_image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffersEXT(1, &_image_framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, &_image_framebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, &_image_framebuffer_texture, 0);
Textured quad with texture that was created from image is drawn to _image_framebuffer:
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, (5*_cg_image_width), (5*_cg_image_height));
glMatrixMode(GL_PROJECTION);
glFrustum(0, (5*_cg_image_width), 0, (5*_cg_image_height), 0.1, 100);
glTranslatef(0.0,0.0,-0.5);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _image_framebuffer);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, (5*_cg_image_width), (5*_cg_image_height));
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _image_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, (5*_cg_image_height));
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f((5*_cg_image_width), 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f((5*_cg_image_width), (5*_cg_image_height));
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
User input is drawn to _brush_framebuffer, and after every new input, everything is drawn to _main_framebuffer like that:
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, (5*_cg_image_width), (5*_cg_image_height));
glMatrixMode(GL_PROJECTION);
glFrustum(0, (5*_cg_image_width), 0, (5*_cg_image_height), 0.1, 100);
glTranslatef(0.0,0.0,-0.5);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _main_framebuffer);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, (5*_cg_image_width), (5*_cg_image_height));
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _image_framebuffer_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, (5*_cg_image_height));
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f((5*_cg_image_width), 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f((5*_cg_image_width), (5*_cg_image_height));
glEnd();
glBindTexture(GL_TEXTURE_2D, _brush_framebuffer_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, (5*_cg_image_height));
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f((5*_cg_image_width), 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f((5*_cg_image_width), (5*_cg_image_height));
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
And then _main_framebuffer is drawn to screen
glLoadIdentity();
glViewport(0, 0, (5*_cg_image_width), (5*_cg_image_height));
glMatrixMode(GL_PROJECTION);
glFrustum(0, (5*_cg_image_width), 0, (5*_cg_image_height), 0.1, 100);
glTranslatef(0,0,-0.5);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _main_framebuffer_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, (5*_cg_image_height));
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f((5*_cg_image_width), 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f((5*_cg_image_width), (5*_cg_image_height));
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
____________________________________________________
Everything works perfectly on my iMac (with AMD Radeon HD 6750M graphics card). But when I launch my app on iMac with NVIDIA GeForce 7300 GT graphics card, images, wich has at least one edge bigger than 800px, are redrawed not correctly. For example:
I have image witch's size is 825x825:
I open this image with my app (so it is being redrawn to openGL, and then without any editings I do glReadPixels and save it to file, so it reads everything what I am seeing in my app's NSOpenGLView (and what I see is distorted image). And repeat this action 8 times (open saved image, save it to file, open newly saved image, and save it to file...) and I get image witch looks like that:
This image is exactly the same what I am seeing in my NSOpenGLView. It is distorted. It has 88pixels spacing from right, 44pixels spacing from bottom, and 44pixels spacing from top, filled with glClearColor.
Another example:
I have image (1000x500):
I do the same as with previous image, just this time, only for 3 times, and I get result image:
witch has 698 pixels spacing from right, filled with glClearColor, and the image is distorted.
By the way, images still has their original dimension, just the view is distorted. How could I fix this issue?
Mac OS X (10.7)