PDA

View Full Version : Real GL_MAX_VIEWPORT_DIMS



LeoGL
12-14-2010, 03:26 AM
My GL_MAX_VIEWPORT_DIMS is 8192 x 8192 but whenever I set the viewport larger than 6500 x 6500 I get a garbage image. If I render to a 7000 x 7000 I get even an empty image (totally transparent and empty). Sometimes I get a crash. And I render an empty scene, just a black background.

How to calculate the real GL_MAX_VIEWPORT_DIMS and avoid the crash?
I need to know that real value so, in case I need to render a larger image, I render to a series of smaller viewport tiles.

I noticed that if the pixel buffer has NSOpenGLPFASampleBuffers 1 and NSOpenGLPFASamples 2, I cannot get a good image larger than 4000 x 4000. So the calculation presumably involves several variables.

My GC is NVIDIA GeForce GT 330M with 512MB VRAM, OpenGL Version: 2.1 NVIDIA-1.6.24. My display size is 1900 x 1200. I run MacOS X 10.6.5.

_arts_
12-14-2010, 04:02 AM
Why do you need a viewport larger than your screen ? I think viewports are connected to display screens.

If you need to render to large images, try to use FBO.

skynet
12-14-2010, 05:35 AM
Why do you need a viewport larger than your screen ? I think viewports are connected to display screens.

The viewport size is independent on window size (though, in most cases you couple them to get a "normal" image).

You may want a viewport _transformation_ (which is controlled by glViewport() that either enlarges or shrinks the output independent on the window.... for instance, you might implment some kind of picture-in-picture effect this way.

One clearification is needed, though.
LeoGL: do you actually refer to a call to glViewport(0,0,6500,6500) or do you try to create an FBO that is so large?

aqnuep
12-14-2010, 08:17 AM
Actually if you are using such a large viewport for rendering to a window then it is not a surprise that it doesn't work as pixel ownership test should discard anything larger than the screen.

If you use FBOs to render to texture then in fact it should work, if not, then it must be most probably a driver bug.

skynet
12-14-2010, 11:07 AM
He said,

...I get a garbage image... ...Sometimes I get a crash.
so it sounds definitely like a driver bug.

LeoGL
12-15-2010, 11:07 AM
Thank you.
I really need to save the openGL scene to a big image.
Actually I "hide" the window (which sounds like a dirty trick, I know), enlarge the window (together with its glView) to the maxDim (8192 x 8192), then I draw the glView once only, then I get the result with glReadPixel and I save the image. I get garbage starting with 6500 x 6500. But if I turn on the supersample NSOpenGLPFASamples I get garbage starting with 4000 x 4000.

Anyway, I have already coded the render-to-tiles method, but I don't really know when I have to apply it, since I can't really know the real max viewport size. I can't say e.g. if the final image is > maxDim/2 I divide the viewport in tiles... Got it?

I am going to try the FBO. I have some question.
a) As I understand I still have to set the viewport, and its max size GL_MAX_VIEWPORT_DIMS is the same. Right?
b) I will close the window and discard the current glView, so, without a glView, when I bind the FBO, which openGL context should I make as current?
c) Should I use a different pixelFormat than the one I use for the glView?

skynet
12-15-2010, 11:17 AM
I really need to save the openGL scene to a big image.
Actually I "hide" the window (which sounds like a dirty trick, I know), enlarge the window (together with its glView) to the maxDim (8192 x 8192), then I draw the glView once only, then I get the result with glReadPixel and I save the image

This is indeed a dirty, evil hack that you deserve to not work! :-D

I doubt that you can "just" enlarge a window beyond the screen size and then expect it to return valid pixel data from the invisible out-of-screen parts. Also, for hidden windows GL's ownership test might just return "false" for every pixel you try to render.

If you want a clean, working solution, always use a tiled renderng (if you want to exceed the maximum viewport/FBO dimension) into an offscreen-FBO.

Apart from that, you should create a bug report/demonstration and forward that to your graphic card vendor. Maybe they have a bug in their implementation because nobody has ever tested such a large viewport setting.

LeoGL
12-15-2010, 11:40 AM
Thank you skynet,
do you have an answer to the 3 questions I posed here above?
I used FBO once (so I am not so skilled on FBO), but always within a glView's drawRect: method, to draw the result to a texture. So the openGL context was set, the pixelFormat too... Here instead I have no glView, so, can I simply define and draw within the FBO? No need to define context and pixelFormat? Also, should I attach a glFramebufferTexture2DEXT or a glFramebufferRenderbufferEXT ?

Alfonse Reinheart
12-15-2010, 12:29 PM
b) I will close the window and discard the current glView, so, without a glView, when I bind the FBO, which openGL context should I make as current?

I don't know what a "glView" is, but if that's anything like an OpenGL context, then you don't have OpenGL without one. If you actually close the window, I'm fairly sure your rendering context goes with it. And without having a valid rendering context, you can't talk to OpenGL.

LeoGL
12-16-2010, 05:15 AM
Thank you Alfonse.
Yes, glView is the openGL view with the openGL context.
Here they suggest to non to draw in the glView but in the FBO.
So, as I understand, to save the hi-res image, I should do the following. Please confirm.

a) I close the window.
b) I do not discard the glView.
c) I create the FBO.
d) I keep on calling the glView's drawRect method, but now, firstly I bind the FBO, then I set the viewport to the hi-res size (no matter the size of the glView), then I draw the scene.

To create the FBO
-------------------------------------------------------------------------
I create the FBO and attach to it a texture with Hi Res size

glGenFramebuffersEXT(1, &mGLFrameBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mGLFrameBuffer);

glGenTextures(1, &mTexBind);
glBindTexture(GL_TEXTURE_2D, mTexBind);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, hr_width, hr_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexBind, 0);
verify, unbind, etc…


To draw
-------------------------------------------------------------------------
// This is the glView's drawRect method, now modified
// to draw in the FBO when I need to save the scene to a file
- (void)drawRect:(NSRect)rect
{
// I bind the FBO then I set the viewport with the Hi-Res size
if(saveImage){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mGLFrameBuffer);
glViewport(0, 0, hr_width, hr_height); // I set the Hi-Res size, no matter the glView's size, right?
}
else{
// if I don't save the scene to an image, I just draw with the glView size
glViewport(0, 0, width, height);
}

glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// I set the projection and modelView matrices and I draw the scene.
// Then I unbind the FBO and get the image with glTexSubImage2D. Correct?

if(saveImage){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

// should I bring the scene to my image buffer this way?
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, hr_width, hr_height, GL_BGRA_EXT, ARGB_IMAGE_TYPE, mImageBufferPtr);
}

[[NSOpenGLContext currentContext] flushBuffer];
}

LeoGL
12-16-2010, 11:39 AM
Ok, I succeeded. That's great!!!
Now I have to deal with a new problem: the FBO has no antialias.
I am trying to make it multiSample. Sometimes it works, sometimes it crashes.
I will deal with it, and in case, I will open a new thread. This forum is great! Thanks.