# Snapshot von einem GLCanvas (OpenGL) in SWT



## commic (13. Juni 2008)

Hallo,

ich versuche einen Schnappschuss von einem GLCanvas in SWT zu machen, in dem ich mit JOGL ein paar Animationen darstelle. Ziel ist es das ganze als BufferedImage zu bekommen. Das klappt auch soweit alles (mit gc.copyArea). Jedoch wird der Inhalt des GLCanvas überhaupt nicht in der erzeugten Bild-Datei angezeigt (ist also nur grau). Hat damit vielleicht jemand ERfahrung von euch und kann mir einen Tip geben ? Ich bin für jede kleine Info dankbar.

ciao,
micha


----------



## hagbard23 (7. August 2008)

ne....aber ich wills auch wissen....mache das grad über das grafik framework(vtk mit java bindings), aber die möglichkeiten sind doch begrenzt.....


----------



## Thomas Darimont (7. August 2008)

Hallo,

https://jogl.dev.java.net/
JOGL: com.sun.opengl.util.Screenshot.writeImageFile(...)

Gruß Tom


----------



## hagbard23 (7. August 2008)

na eben net aus der lib, sondern über den rendercontext im glcanvas, unabhängig von der grafiklib....


----------



## Thomas Darimont (7. August 2008)

Hallo,

wie meinst du das? Da der Geräte-Kontext innerhalb des GLCanvas dann von der jeweiligen OpenGL Bibliothek verwaltet wird, hast du da mit normalen SWT mitteln IMHO keinen Zugriff drauf. Die Contents des entsprechenden Bereichs musst du dann schon über die OpenGL Bibliothek deiner Wahl direkt ansprechen.

Wie gesagt eine Möglichkeit wäre hier (bei Verwendung von JOGL) diese hier:

```
package de.tutorials.eclipse.training;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.glu.GLU;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

import com.sun.opengl.util.Screenshot;

public class Snippet209 {
    static void drawTorus(GL gl, float r, float R, int nsides, int rings) {
        float ringDelta = 2.0f * (float) Math.PI / rings;
        float sideDelta = 2.0f * (float) Math.PI / nsides;
        float theta = 0.0f, cosTheta = 1.0f, sinTheta = 0.0f;
        for (int i = rings - 1; i >= 0; i--) {
            float theta1 = theta + ringDelta;
            float cosTheta1 = (float) Math.cos(theta1);
            float sinTheta1 = (float) Math.sin(theta1);
            gl.glBegin(GL.GL_QUAD_STRIP);
            float phi = 0.0f;
            for (int j = nsides; j >= 0; j--) {
                phi += sideDelta;
                float cosPhi = (float) Math.cos(phi);
                float sinPhi = (float) Math.sin(phi);
                float dist = R + r * cosPhi;
                gl.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
                gl.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
                gl.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
                gl.glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
            }
            gl.glEnd();
            theta = theta1;
            cosTheta = cosTheta1;
            sinTheta = sinTheta1;
        }
    }

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        Composite comp = new Composite(shell, SWT.NONE);
        comp.setLayout(new FillLayout());
        GLData data = new GLData();
        data.doubleBuffer = true;
        final GLCanvas canvas = new GLCanvas(comp, SWT.NONE, data);

        canvas.setCurrent();
        final GLContext context = GLDrawableFactory.getFactory()
                .createExternalGLContext();

        canvas.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event event) {
                Rectangle bounds = canvas.getBounds();
                float fAspect = (float) bounds.width / (float) bounds.height;
                canvas.setCurrent();
                context.makeCurrent();
                GL gl = context.getGL();
                gl.glViewport(0, 0, bounds.width, bounds.height);
                gl.glMatrixMode(GL.GL_PROJECTION);
                gl.glLoadIdentity();
                GLU glu = new GLU();
                glu.gluPerspective(45.0f, fAspect, 0.5f, 400.0f);
                gl.glMatrixMode(GL.GL_MODELVIEW);
                gl.glLoadIdentity();
                context.release();
            }
        });

        context.makeCurrent();
        GL gl = context.getGL();
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        gl.glColor3f(1.0f, 0.0f, 0.0f);
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        gl.glClearDepth(1.0);
        gl.glLineWidth(2);
        gl.glEnable(GL.GL_DEPTH_TEST);
        context.release();

        shell.setText("SWT/JOGL Example");
        shell.setSize(640, 480);
        shell.open();

        display.asyncExec(new Runnable() {
            int rot = 0;

            boolean tookScreenshot;
            
            public void run() {
                if (!canvas.isDisposed()) {
                    canvas.setCurrent();
                    context.makeCurrent();
                    GL gl = context.getGL();
                    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                    gl.glClearColor(.3f, .5f, .8f, 1.0f);
                    gl.glLoadIdentity();
                    gl.glTranslatef(0.0f, 0.0f, -10.0f);
                    float frot = rot;
                    gl.glRotatef(0.15f * rot, 2.0f * frot, 10.0f * frot, 1.0f);
                    gl.glRotatef(0.3f * rot, 3.0f * frot, 1.0f * frot, 1.0f);
                    rot++;
                    gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
                    gl.glColor3f(0.9f, 0.9f, 0.9f);
                    drawTorus(gl, 1,
                            1.9f + ((float) Math.sin((0.004f * frot))), 15, 15);
                    canvas.swapBuffers();
                    
                    if(rot > 100 && !tookScreenshot){
                        makeScreenShot(shell);
                    }
                    
                    context.release();
                    
                    
                    display.asyncExec(this);
                }
            }

            private void makeScreenShot(final Shell shell) {
                Rectangle bounds = shell.getBounds();
                
                try {
                    Screenshot.writeToFile(new File("c:/jogl.jpg"),
                            bounds.width, bounds.height);
                    tookScreenshot= true;
                    System.out.println("Took screenshot...");
                } catch (GLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}
```

Gruß Tom


----------



## hagbard23 (7. August 2008)

na ja...ich denke einfach, dass solange ich die pixel rendern kann, ich sie auch außerhalb von der grafiklib abgreifen köbnnen müsste....


----------



## Thomas Darimont (7. August 2008)

Hallo,

schon klar... kommt eben nur drauf an ob du auf das Rendering-Device auch Zugriff hast ... probiers doch mal über den java.awt.Robot.

Gruß Tom


----------



## hagbard23 (8. August 2008)

wasn das? nen gui klick bot? wie soll mir das helfen....im grund suche ich nach ner möglichkeit, avis aus meinem 3d ansichtsfensater zu schreiben, wobei man auch z.b. die auflösung konfigurieren können sollte....hmmm


----------



## Thomas Darimont (8. August 2008)

Hallo,

du solltest vielleicht erst mal die Doku durchschauen bevor du irgendwas schreibst...:
java.awt.Robot -> createScreenCapture(...)
Damit funktionierts übrigens btw...

Gruß Tom


----------



## hagbard23 (8. August 2008)

hmmm....ja das wäre sinnvoll.....sieht ja ganz sinnig aus....das java.awt.Robot sieht ja ganz coll aus....damit lassen sich bestimmt auch selbstlaufende tutorials innerhalb von einer applikation umsetzen....


----------

