It works like that:
[ul]
[li]Read image (create NSImage from image url)[/li][li]Create NSBitmapImageRep from NSImage[/li][li]Copy NSBitmapImageRep, and create CIImage from that[/li][li]Apply CIFilter on CIImage to get grayscale image version[/li][li]Create NSBitmapImageRep from CIImage[/li][li]Create 2 textures[/li][li]Add texture’s image (texture1 - normal image bitmap, texture2 - grayscale image bitmap)[/li][li]Create 3 framebuffers (mainframebuffer, normalframebuffer, grayscaleframebuffer)[/li][li]Draw normal image texture to normalframebuffer and gray scale image texture to grayscaleframebuffer[/li][li]Draw both framebuffers to mainframebuffer (1st normalframebuffer and then grayscaleframebuffer on top of it)[/li][li]Draw main framebuffer to screen[/li][/ul]
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, _fullWidth, _fullHeight);
glMatrixMode(GL_PROJECTION);
glFrustum(0, _fullWidth, 0, _fullHeight, 0.1, 100);
glTranslatef(0.0,0.0,-0.5);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, normalframebuffer);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, _fullWidth, _fullHeight);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, normalimagetextur);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, _fullHeight);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_fullWidth, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_fullWidth, _fullHeight);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, _fullWidth, _fullHeight);
glMatrixMode(GL_PROJECTION);
glFrustum(0, _fullWidth, 0, _fullHeight, 0.1, 100);
glTranslatef(0.0,0.0,-0.5);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frontframebuffer);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, _fullWidth, _fullHeight);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
glBindTexture(GL_TEXTURE_2D, grayscaleimagetexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, _fullHeight);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_fullWidth, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_fullWidth, _fullHeight);
glEnd();
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
_fullWidth is 5*image width (everything is drawn 5 times bigger than it realy is, to achieve zoom-in effect with glTranslatef
Everything is drawn to main framebuffer like that:
glPushMatrix();
glLoadIdentity();
glViewport(0, 0, _fullWidth, _fullHeight);
glMatrixMode(GL_PROJECTION);
glFrustum(0, _fullWidth, 0, _fullHeight, 0.1, 100);
glTranslatef(0.0,0.0,-0.5);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mainframebuffer);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, _fullWidth, _fullHeight);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, normalframebuffertexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, _fullHeight);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_fullWidth, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_fullWidth, _fullHeight);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
glBindTexture(GL_TEXTURE_2D, grayscaleframebuffertexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, _fullHeight);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_fullWidth, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_fullWidth, _fullHeight);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glPopMatrix();
And then drawn to screen like that:
float zoom = [zoomSlider floatValue];
glLoadIdentity();
visibleRect = [self visibleRect];
glViewport(0, 0, NSWidth(visibleRect), NSHeight(visibleRect));
glMatrixMode(GL_PROJECTION);
glFrustum(NSMinX(visibleRect), NSMaxX(visibleRect), NSMinY(visibleRect), NSMaxY(visibleRect), 0.1, 100);
glTranslatef(0,0,zoom);
glClearColor(0.93, 0.93, 0.93, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, _fullHeight);
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex2f(_fullWidth, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex2f(_fullWidth, _fullHeight);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
Texture’s and framebuffers size is equal to original image size. So it doesn’t exceeds size limits.
Example:
Images from OS->Library->Desktop Pictures:
Floating Leaves.jpg -> redraws not correctly. Dimensions: 3200x2000.
Forest in Mist.jpg -> redraws not correctly. Dimensions: 3200x2000.
Other images from desktop pictures gets redrawed correctly but app gets bad image size (not 3200x2000)
Other images:
mirage-2000.jpg -> redraws not correctly. Dimensions 1024x768.
So it looks like the problem is not only in image size.