remember last drawing

hello,
i am trying write a Paint application using jogl.

when i draw some shape on a canvas, i want it to remain there. but when i begin to draw new shape, old shape is gone.

do you a way of saving the view and drawing new shapes on old view.

the answer may not be related to jogl, i kinda remember something like canvas on canvas that is making old canvas a background of new one.

i modify code from a jogl demo.

class Renderer
implements GLEventListener,
MouseListener, MouseMotionListener {

.
.
.
public void display(GLDrawable gLDrawable) {
final GL gl = gLDrawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(-2.5f, 0.0f, -10.0f);
gl.glBegin(GL.GL_TRIANGLES); // Drawing Using Triangles

    gl.glColor3f(1.0f, 0.0f, 0.0f);   // Set the current drawing color to red

    gl.glEnd();                        // Finished Drawing The Triangle

    gl.glTranslatef(1.0f, 0.0f, 0.0f);
    gl.glBegin(GL.GL_QUADS);                 // Draw A Quad

    gl.glColor3f(0.5f, 0.5f, 1.0f);   // Set the current drawing color to light blue
    if (dragPoint != null ){
        gl.glVertex3f(-1.0f, 1.0f, 0.0f);      // Top Left

        gl.glVertex3f(0.0f, 1.0f, 2.0f);      // Top Right

        gl.glVertex3f(1.0f, -1.0f, 0.0f);      // Bottom Right

        gl.glVertex3f(-1.0f, -1.0f, 1.0f);      // Bottom Left
    } else   {
        gl.glVertex3f(-1.0f, 1.0f, 0.0f);      // Top Left

        gl.glVertex3f(0.0f, 1.0f, 0.0f);      // Top Right

        gl.glVertex3f(1.0f, 0.0f, 0.0f);      // Bottom Right

        gl.glVertex3f(-1.0f, -1.0f, 0.0f);      // Bottom Left

    }

    gl.glEnd();                        // Done Drawing The Quad

    gl.glFlush();
}

.
.
public void mousePressed(MouseEvent e) {
lastPressed = e.getPoint();
}

public void mouseReleased(MouseEvent e) {
    lastPressed = null;
    dragPoint = null;
}

.
.
}

you have just to store them and repaint each time inside display method.

D.

that is what i was think of at first. but i want to make sure that there isn’t an easy way.

thank you.

[quote]that is what i was think of at first. but i want to make sure that there isn’t an easy way.
[/quote]
Well, it’s not that difficult. You could store your previous image as a texture and then draw that on the canvas before drawing anything else on it. Hmmm, it might be best to use a non-power-of-two texture for that.

First you have to create such a container texture:


    public int createTexture(int width, int height, GL gl)
    {
        int[] textureHandles = new int[1];
        gl.glGenTextures(1, textureHandles);
        textureHandle = textureHandles[0];

        int textureData[] = new int[width * height * 3];

        gl.glEnable(GL.GL_TEXTURE_RECTANGLE_EXT);
        gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_EXT, textureHandle);
        gl.glTexImage2D(GL.GL_TEXTURE_RECTANGLE_EXT, 0, 3, width, height, 0, GL.GL_RGB, GL.GL_UNSIGNED_INT, textureData);
        gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_EXT, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
        gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_EXT, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
        gl.glDisable(GL.GL_TEXTURE_RECTANGLE_EXT);

return textureHandle;
    }

Now, you can use the previous piece of code to create the texture (in reshape method for example):


int canvasTexture = createTexture(viewPortWidth, viewPortHeight, gl);

Then later on, you can copy the current viewport data to the container texture like this:


    public void copyCanvas(int textureHandle, int width, int height, GL gl)
    {
        gl.glEnable(GL.GL_TEXTURE_RECTANGLE_EXT);
        gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_EXT, textureHandle);
        gl.glCopyTexSubImage2D(GL.GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, 0, 0, width, height);
        gl.glDisable(GL.GL_TEXTURE_RECTANGLE_EXT);
    }

Now, just call it like this:


copyCanvas(canvasTexture, viewPortWidth, viewPortHeight, gl);

To actually render the previously stored texture to screen, you need something like the following:


    public void restoreCanvas(int textureHandle, int width, int height, GL gl)
    {
        gl.glEnable(GL.GL_TEXTURE_RECTANGLE_EXT);
        gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_EXT, textureHandle);

            viewOrtho(gl);
            gl.glBegin(GL.GL_QUADS);
            {
                 gl.glTexCoord2f(width, 0);
                gl.glVertex2f(0, 0);
                gl.glTexCoord2f(width, height);
                gl.glVertex2f(0, 1.0f);
                gl.glTexCoord2f(0, height);
                gl.glVertex2f(1.0f, 1.0f);
                gl.glTexCoord2f(0, 0);
                gl.glVertex2f(1.0f, 0);
            }
            gl.glEnd();
            viewPerspective(gl);

        gl.glDisable(GL.GL_TEXTURE_RECTANGLE_EXT);
    }

    private void viewOrtho(GL gl)
    {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        gl.glOrtho(1, 0, 0, 1, -1, 1000000);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();
    }

    private void viewPerspective(GL gl)
    {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();
    }

And to use that:


restoreCanvas(canvasTexture, viewPortWidth, viewPortHeight, gl);

Hope this helps a bit and sorry for the messed up code indentations…

Cheers

Hallo!

The code above is good, but I have a problem with the following:

I paint 3 differentcolored quads in my 300x300 window, each quad 100x100 and from left bottom to right top.

1st try:
1.quad = red
2.quad = green
3.quad = blue
=> restoreTexture draws only the blue one

2nd try:
1.quad = white
2.quad = green
3.quad = blue
=> restoreTexture draws the blue one, and the white one in blue color!

etc.

Why is it so? How can I handle this problem?

P.S. the blue one is drawn at last.
P.P.S. I use windows and jogl. <- Maybe here’s the problem?

Does everything drawn stay on the canvas forever? Could you get away with just neglecting to clear the framebuffer?

i clear the color buffer, load with code above the texture and there are problems.

i have “solved” it by adding a white color, while drawing the texture. but why does it solve the problem? i dont have any alpha or blending or depth enabled.