Smooth Scrolling text.

Hello all,

I am writing a prompter that is supposed to scroll text as smoothly as possible. I have had some success, but how smoothly the text scrolls seems to vary in ways that I don’t understand. I hope if I could understand why, I might be able to make it always scroll as smoothly as the smoothest that it scrolls now.

Currently, this is how I am doing it.
I wrap the text and draw one paragraph using the graphics from a BufferedImage (I used to use a TextRenderer and TextureRenderer but neither one of them are any faster: the problem isn’t with drawing it to a texture, but with drawing the texture). Then I create a call list for each paragraph to draw its texture. Then I make a call list for calling each of these call lists that fit on the screen.

I would be happy to post more of my code, but I am not sure which parts will be the most helpful.

Here is how I create texture (Do not concern yourself with using the BufferedImage first, I will explain that):


		BufferedImage image = new BufferedImage(size.width, (int) height, BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics = (Graphics2D) image.getGraphics();

		graphics.fillRect(...);

		for (Line line : lines) {
			ArrayList<TextLayout> layouts = line.layouts;
			ArrayList<Float> horizontalPoses = line.horizontalPoses;
			for (int i = 0; i < layouts.size(); i++) {
				layouts.get(i).draw(graphics, horizontalPoses.get(i),
						line.ypos);
			}
		}

		//Texture paragraph = tr.getTexture();
		int w = (int) (settings.getScaleFactor() * size.width);
		int h = (int) (settings.getScaleFactor() * height);

		BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		resized.getGraphics().drawImage(image, 0, 0, w, h, null);
		Texture paragraph = AWTTextureIO.newTexture(gl.profile, resized, true);

		paragraph.setTexParameteri(gl.gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
		paragraph.setTexParameteri(gl.gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
		paragraph.setTexParameteri(gl.gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
		paragraph.setTexParameteri(gl.gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);

Here is how I create the paragraph call list:

		float y2 = -2 * height / size.height; // multiply by scale here?

		if (texture.getMustFlipVertically()) {
			float tmp = y1;
			y1 = y2;
			y2 = tmp;
		}

		gl.gl.glNewList(displayLists.get(gl), GL2.GL_COMPILE);
		texture.bind(gl.gl);
		gl.gl.glBegin(GL2.GL_QUADS);
		{
			gl.gl.glTexCoord2d(0.0, 0.0);
			gl.gl.glVertex2f(x1, y2);
			gl.gl.glTexCoord2d(1.0, 0.0);
			gl.gl.glVertex2f(x2, y2);
			gl.gl.glTexCoord2d(1.0, 1.0);
			gl.gl.glVertex2f(x2, y1);
			gl.gl.glTexCoord2d(0.0, 1.0);
			gl.gl.glVertex2f(x1, y1);
		}
		gl.gl.glEnd();
		gl.gl.glEndList();

Here is what I run inside of my animator’s display call:



				gl.glTranslatef(...);

				if (prevBegin == startIndex && prevEnd == endIndex && call) {
					gl.glCallList(curList);
				} else {
					prevBegin = startIndex;
					prevEnd = endIndex;
					gl.glNewList(curList, GL2.GL_COMPILE_AND_EXECUTE);
					gl.glClear(GL.GL_COLOR_BUFFER_BIT);

					int indx = startIndex;
					for (;;) {
						Drawable d = rr.get(indx);
// this is a call to 
//		gl.glCallList(displayList); with the Drawable's displayList
						draw(gl, d);

						if (endIndex < ++indx) {
							break;
						}
						gl.glTranslatef(0f, -2 * d.getHeight() / getHeight(), 0);
					}

					gl.glLoadIdentity();
					gl.glEndList();
					call = true;
				}

				if (cloneView != null) {
					cloneView.display();
				}

I create a BufferedImage first because I was experimenting with resizing the texture to save space: but this did very little for me.

Using call lists doesn’t make it one bit smoother. I enable double buffering, and set the vertical refresh rate to fix the tearing. The problem is that on my computer the cloneView (which is another GLCanvas that shares the textures from the main canvas) is MUCH smoother than the main prompter. It doesn’t matter if call lists are enabled on either canvas, or if I apply an extra transformation (like rotating the text upside down). However, if I use a different animator (instead of calling the the main cloneView’s display() method while inside the main prompter’s display(gl)), then they are both slow.

Unfortunately, that is only on my computer: even on much nicer computers, both canvases are jerky (jerky as in make large jumps in when scrolling). I have asked for help on here before, and I received many warm-hearted suggestions (Thanks!) but none of them have smoothed the scrolling. If somebody can think of some variable that would be affecting the smoothness, it would help a lot! I can clarify anything that doesn’t make sense.

Hi

Have you tried the new shader-based text renderer (only in JOGL 2.0)? I think you might get a nice result using it with PBO. You should ask your question on the official JogAmp forum too in order to get more replies as some JOGL experts don’t come here.

You might ignore all the complexity (no text, no display lists) for now and try to simply get an image to scroll smoothly. I guess you are using OpenGL in a Swing app?