Using enableGLCanvasRenderer

Started by Mr.Marbles, January 18, 2006, 05:18:30 PM

Previous topic - Next topic

Mr.Marbles

I need to render into a JPanel component, so I'm using the following code:

Canvas myCanvas = frameBuffer.enableGLCanvasRenderer(IRenderer.MODE_OPENGL);
JPanel panel = new JPanel();
panel.add(myCanvas);

Now if I want to switch to a software renderer I can do the following:

frameBuffer.disableRenderer(IRenderer.RENDERER_OPENGL);
frameBuffer.enableRenderer(IRenderer.RENDERER_SOFTWARE, IRenderer.MODE_OPENGL);

My question is what's the difference, when using software rendering, to render to a Canvas or to a Graphics object such as:

Graphics g = panel.getGraphics();
frameBuffer.display(g);

Is one method better than the other in terms of performance?

EgonOlsen

The AWTGLCanvas is a Canvas by design. The software renderer renders into an Image. You can either use that directly, or let the FrameBuffer itself draw it into a Graphics context or even use the pixels array....
To be honest, i don't really understand the question... :?:

Mr.Marbles

EgonOlsen,

I'm sorry if my question was unclear, I will try to elaborate. Is there a "best" way for doing software rendering? I noticed that using a Canvas:
Canvas myCanvas = frameBuffer.enableGLCanvasRenderer(IRenderer.MODE_OPENGL);
JPanel panel = new JPanel();
panel.add(myCanvas);
.
.
.
private void display()
{
   frameBuffer.clear();
   theWorld.renderScene(frameBuffer);
   theWorld.draw(frameBuffer);
   frameBuffer.update();

   myCanvas.refresh();
}

and using the Graphics context:
JPanel panel = new JPanel();
Graphics g = panel.getGraphics();
.
.
.
private void display()
{
   frameBuffer.clear();
   theWorld.renderScene(frameBuffer);
   theWorld.draw(frameBuffer);
   frameBuffer.update();

   frameBuffer.display(g);
}

do exactly the same thing. Which is the "better" way?

EgonOlsen

The first example (except that it's Canvas.repaint(), not refresh()) doesn't do software rendering but uses the hardware renderer. Only the second one is software. I guess that's why i don't fully understand the question.
Anyway, they are not doing the same thing. The first one uses passive rendering, the second one active. I.e. in the second example, the pixels are being painted when you call display(g). You can rely on that after the call, the Panel shows the current frame. This isn't the case in the first example. repaint() just schedules the component for a repaint, it doesn't actually paint anything. Painting is done in the awt event dispatch thread when the VM thinks it's time to.
Ignoring the fact that we are comparing apples (software) to bananas (hardware) here, the former way of doing things is mandatory when using a GLCanvasRenderer and usefull for frames that should integrate into Swing/AWT-GUIs (by putting the display(g) call into the paint()-method of the component) when using software rendering.
The latter way is better when using software rendering without any further GUI elements because it gives you total control of what to paint when.

Mr.Marbles

What if I create the  Canvas like this:
Canvas myCanvas = frameBuffer.enableGLCanvasRenderer(IRenderer.RENDERER_SOFTWARE);
Won't this imply software rendering into the Canvas object?

Mr.Marbles

I think I understand now. After reviewing the javadoc for the IRenderer class I see that the "mode" only determines what type of lighting model the renderer will use. So enableGLCanvasRenderer will always be rendering in hardware and never in software. Therefore there are no 'Canvas-type' components in which software rendering can be done. It seems the only way to render via software is to use the FrameBuffer.draw(Graphics). Furthermore, there are exactly two ways to render via hardware; using enableGLCanvasRenderer, or using FrameBuffer.displayGLOnly() (with a FrameBuffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL) call).

Melssj5

Of course you can do it.

If you want to render by software inside a canvas you just need to use a comon awt canvas and use display (Graphics g); method to render.

To make the images appear on the canvas you must put the rendering code inside the paint method of the canvas.

public void paint (Graphics g) {
//your rendering code.
}
Nada por ahora

Mr.Marbles

Melssj5,

Yes, you're absolutely right. I didn't write my statement properly. I meant that there are no 'Canvas-type' components that are returned by a class in the jpct lib into which a software renderer will automatically draw a rendered frame; i.e. without calling a FrameBuffer.draw(Graphics).

Just to add to your post: any subclass of java.awt.Component can be potentially used as a rendering host for FrameBuffer.draw(Graphics)  :wink:

EgonOlsen

Quote from: "Mr.Marbles"It seems the only way to render via software is to use the FrameBuffer.draw(Graphics). Furthermore, there are exactly two ways to render via hardware; using enableGLCanvasRenderer, or using FrameBuffer.displayGLOnly() (with a FrameBuffer.enableRenderer(IRenderer.RENDERER_OPENGL, IRenderer.MODE_OPENGL) call).
You may also get the rendered Image from the FrameBuffer and do something with that and even the pixels-int[]-array is available.
You are right about hardware rendering. The two ways use completely different renderers. The reason why the enableGL...exist is, that is has to return a Canvas to be of any use while the enableRenderer can't do that.