PDA

View Full Version : simple 2D app. w/ unintended blur during motion



codebreaker
06-18-2010, 06:36 AM
Hi. I am just starting in OpenGL programming with a background in C/C++, Java, and other languages - so I suspect that I am missing a very simple protocol or setting that results in my issue. Any help would be appreciated.

The application: draw a set of vertical bars in an OpenGL window, then set them in motion across the window (horizontally). Implementation of the motion uses an animation thread to periodically render the scene. Rendering is performed simply by clearing the buffer and then redrawing the vertical bars at an offset determined by the given rate of traversal across the window. So, I clear and redraw the entire display for each rendering (at least I think that's what I'm doing ;) ). I turned off dithering, blending, and all anti-aliasing (point, line, polygon), and have even set up a clear for the accumulator (which is performed with, and with the same data as, the color buffer clear). I have also tried a version of the program that uses integer (rather than float) values for the screen postitioning data - no effect.

The problem: when the traversal rate is 0 (bars are not moving), the edges of the bars are well defined. As soon as the bars are set in motion, the edges start to fuzz or blur (on most hardware). The extent of the fuzz seems to increase roughly in proportion to the rate of traversal.

The hardware: a number of different platforms were tested. Some might be a couple of years old, and this *might* be part of the issue, but the problem occurs on a MacBook Pro (XCode OpenGL framework) that is less than a year old as well as on several Windows machines (Java JOGL). Interestingly, a NVidia GeForce4 Ti 4200 (AGP8X) w/ Windows does *not* exhibit the problem - edges remain well defined at all traversal rates. Yes, I made sure I had up to date video drivers and software on all tested platforms.

Is there some control (maybe something to do with motion blur?) that I am missing that could eliminate this effect?

Also, I seem to have some jumpy behavior when running the app on my MacBook, I think due to OS scheduling - is there a way to eliminate that as well?

Some java code - I know, I can improve efficiency by running the vertex definitions in a loop inside a glbegin ;), but that is not the issue.

... init:

public void init(GLAutoDrawable drawable) {
mygl = drawable.getGL();
mygl.setSwapInterval(1);
mygl.glMatrixMode(GL.GL_MODELVIEW);
mygl.glLoadIdentity();
mygl.glDisable(GL.GL_BLEND);
mygl.glDisable(GL.GL_DITHER);
mygl.glDisable(GL.GL_POINT_SMOOTH);
mygl.glDisable(GL.GL_LINE_SMOOTH);
mygl.glDisable(GL.GL_POLYGON_SMOOTH);
colorSetup();
}

... display:

public void display(GLAutoDrawable drawable) {
if (con.isColorChanged()) { colorSetup(); }
mygl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_ACCUM_BUFFER_BIT);
for (double x = offset - 1.0 - con.getStripWidth(); x < 1.0; x += con.getStripWidth()) {
drawStrip(mygl, x);
}
offset += con.getShiftDistance();
if (offset > 0) offset = - con.getStripWidth() + offset % con.getStripWidth();
}

void drawStrip(GL gl, double position) {
gl.glBegin(GL.GL_QUADS);
gl.glVertex2d(position, 1.0);
gl.glVertex2d(position, -1.0);
gl.glVertex2d(position + con.getLineWidth(), -1.0);
gl.glVertex2d(position + con.getLineWidth(), 1.0);
gl.glEnd();
}



Thanks in advance for any assistance! Please let me know if more information is required and I will do my best to provide it.

carsten neumann
06-18-2010, 09:13 AM
Is it possible that you are rendering into the front buffer or your rendering is not synchronized with the buffer swap?

codebreaker
06-18-2010, 10:51 AM
Anything is possible! Thanks much for your reply.

I added a line in init:
mygl.glDrawBuffer(GL.GL_BACK);
This did *not* help with the blurring issue, but did resolve a rendering problem I saw with some ATI cards.

My original code has a setSwapInterval(1); in init, is there something else that is required to synchronize the buffer swaps?

Dark Photon
06-19-2010, 04:34 PM
mygl.glDrawBuffer(GL.GL_BACK);
Be sure to do that before you call glClear.

Also, if you don't need an accumulation buffer, don't allocate one, and don't clear it. The blur makes me think you're doing something wrong with the accumulation buffer that you don't know your doing OR that your glClear isn't working the way you intend it to.

Be conscious too that the operation of glClear depends on "pixel ownership test, the scissor test, dithering, and the buffer writemasks". So make sure you're not using scissoring, and I'd slap a glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); right before the glClear just for good measure. :)

codebreaker
06-21-2010, 06:47 AM
I have to believe that this blur is something to do with synchronization of the display function and the screen refresh. I still have the blur on several platforms. My modifications had no effect on platforms that do not exhibit the blur. I should mention that I have configured a small Quartz application that should result in the same effect I am trying to achieve with OpenGL, and I got the same blurring effect there! I have not yet worked on adjusting parameters in Quartz yet to try to eliminate it.

Maybe I am seeing multiple executions of the display function for each screen refresh? Is there something other than setSwapInterval(1) that is required to force a single execution of the display function per screen refresh?

I eliminated the Accum buffer ops, per your suggestion, and there was no effect. I also disabled a plethora of features. Still have the blur on several hardware platforms. My initialization now looks like this:

public void init(GLAutoDrawable drawable) {
mygl = drawable.getGL();
mygl.glMatrixMode(GL.GL_COLOR);
mygl.glLoadIdentity();
mygl.glDisable(GL.GL_BLEND);
mygl.glDisable(GL.GL_DITHER);
mygl.glDisable(GL.GL_POINT_SMOOTH);
mygl.glDisable(GL.GL_POINT_SPRITE);
mygl.glDisable(GL.GL_LINE_SMOOTH);
mygl.glDisable(GL.GL_POLYGON_SMOOTH);
mygl.glDisable(GL.GL_MULTISAMPLE);
mygl.glDisableClientState(GL.GL_COLOR_ARRAY);
mygl.glDisableClientState(GL.GL_SECONDARY_COLOR_AR RAY);
mygl.glDisableClientState(GL.GL_VERTEX_ARRAY);
mygl.glDisable(GL.GL_COLOR_SUM);
mygl.glDisable(GL.GL_MINMAX);
mygl.glDisable(GL.GL_POLYGON_OFFSET_FILL);
mygl.glDisable(GL.GL_POLYGON_OFFSET_POINT);
mygl.glDisable(GL.GL_POLYGON_OFFSET_LINE);
mygl.glDisable(GL.GL_POST_COLOR_MATRIX_COLOR_TABLE );
mygl.glDisable(GL.GL_POST_CONVOLUTION_COLOR_TABLE) ;
mygl.glDrawBuffer(GL.GL_BACK_LEFT);
mygl.setSwapInterval(1);
colorSetup();
}

And my display function like this:

public void display(GLAutoDrawable drawable) {
if (con.isColorChanged()) { colorSetup(); }
mygl.glClear(GL.GL_COLOR_BUFFER_BIT);
mygl.glBegin(GL.GL_QUADS);
for (double x = offset - 1.0 - con.getStripWidth();
x < 1.0; x += con.getStripWidth()) {
mygl.glVertex2d(x, 1.0);
mygl.glVertex2d(x, -1.0);
mygl.glVertex2d(x + con.getLineWidth(), -1.0);
mygl.glVertex2d(x + con.getLineWidth(), 1.0);
}
mygl.glEnd();
mygl.glFinish();
offset += con.getShiftDistance();
if (offset > 0) offset = - con.getStripWidth() + offset % con.getStripWidth();
}

codebreaker
06-21-2010, 06:51 AM
Durn - forgot to mention, in my color function, I also implemented the ColorMask as you suggested ...

mygl.glColorMask(true, true, true, true);
mygl.glClearColor(vColor[0], vColor[1], vColor[2], (float)0.0);
mygl.glColor3f(lColor[0], lColor[1], lColor[2]);

codebreaker
06-22-2010, 06:02 AM
I had another thought, maybe someone can comment. I am using swing components to display some controls (sliders, text boxes, etc.). Is it possible that swing is interfering with my settings? I.e., could it be applying its own settings after I apply mine, thus overriding my settings?

sgsrules
06-22-2010, 04:32 PM
it looks like the problem is with

mygl.glClearColor(vColor[0], vColor[1], vColor[2], (float)0.0);

you have the alpha set to 0. Try setting it to 1.0 so that when it clears, it's opaque.

mygl.glClearColor(vColor[0], vColor[1], vColor[2], 1.0f);

codebreaker
06-23-2010, 04:06 AM
I tried setting the glClearColor alpha to 1.0, but it had no effect. Just for my understanding, would the alpha value have any effect when blending is disabled? Is there something other than blending that alpha is used for?

Also, concerning the blur, is there something in Java or Swing that might be sharing the graphics context under the covers?

ZbuffeR
06-23-2010, 04:43 AM
Can you screenshot this blur ?
A wild guess here, maybe the blur is due to the screen itself ?
It is still there with a CRT monitor ?

An interaction with Swing does not seem likely.

codebreaker
06-23-2010, 05:41 AM
ZbuffeR, you are my hero. I had not thought about the display devices - something I will remember in the future!

The system that I had a clear picture on was indeed a CRT. The other systems were running LCDs of various types.

I switched the monitor for the system that had the blur issue to a CRT and, voila, the blur is gone.

Thanks very much for your input!!!

ZbuffeR
06-23-2010, 06:18 AM
Glad that helped !
:)