PDA

View Full Version : nVidia GeForce 7300 and all other older mac's video cards and textures > 800



hockeyman
10-29-2012, 05:55 AM
I have met the problem while drawing textured quad (texture is from image) with openGL on GeForce 7300. It redraws not correctly.

For example I have image (825x825):
893

I redraw (How it is redrawn I will explain later) it with openGL, then glreadpixels and save to file. Then open saved file, redraw again, and again glreadpixels and save to file. And repeat that 8 times. So after 8th time I have image that looks like that:

894

This image has 88 pixels space from right side, and 44 pixels from top and 44 pixels from bottom, that is filled with glClearColor. And the image is distorted, as you see. If original image size is for example 800x800, everything is OK. The distortion depends on how much one or other edge of image is bigger than 800 pixels. For example if I have image (1000x500):

895

And Open, then save, then open saved image and save again, and so on for 3 times, I get image:

896

witch has 698 pixels space from right filled with glClearColor.


Redrawing process:

1. Create CGImage from opened file, then draw CGContext to GLubyte storage.


_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);


2. Create Texture with these parameters:


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);


3. Add texture image 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);

4. Create framebuffer_1, and mainframebuffer with code like that:


glGenTextures(1, &framebuffer_1_txt);
glBindTexture(GL_TEXTURE_2D, &framebuffer_1_txt);
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, &framebuffer_1);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, &framebuffer_1);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, &framebuffer_1_txt, 0);


5. Draw textured quad with texture that I have created from image, to framebuffer_1.


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, framebuffer_1);
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();


6. Draw textured quad with framebuffer_1 texture to mainframebuffer.


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, mainframebuffer);
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, framebuffer_1_txt);
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();

7. Draw mainframebuffer 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, mainframebuffer_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();


All framebuffers are created succesfully with no errors.

With newer graphics card (for example AMD Radeon HD 6750M) it works good.
So where could be my problem?