# JOGL und TextRenderer



## Evolver (14. Apr 2009)

Ich habe ein kleines Problem mit der (2D) Textdarstellung bei Verwendung des com.sun.opengl.util.j2d.TextRenderer und JOGL. Und zwar wird der Text nicht da dargestellt, wo ich das möchte. Ich benutze JOGL nur zweidimensional, also initialisiere ich die Ansicht wie folgt:

```
gl.glMatrixMode( GL.GL_PROJECTION );
gl.glLoadIdentity();
gl.glViewport( 0, 0, width, height );
gl.glOrtho( 0, width, height, 0, 0, 128 );
```
Dadurch habe ich eine normale Zeichenfläche wie in Java2D. Wenn ich jetzt aber den TextRenderer verwende, hat der seinen Koordinatenursprung links unten.

```
textRenderer = new TextRenderer( new Font( "SansSerif", Font.PLAIN, 11 ) );
//...
textRenderer.beginRendering( drawable.getWidth(), drawable.getHeight() );
textRenderer.setColor( 0.8f, 0.85f, 0.775f, 1.0f );
textRenderer.draw( "Blabla", 20, 20 );
textRenderer.endRendering();
```
Wie bekomme ich ihn dazu, das gleiche Koordinatensystem zu verwenden, das ich sonst auch zum Zeichenen nutze?


----------



## Evolver (16. Apr 2009)

Hat denn niemand Erfahrungen mit dem TextRenderer? Was nutzt ihr denn alternativ zur 2D-Textdarstellung unter JOGL?


----------



## Spacerat (17. Apr 2009)

Mit dem TextRenderer nicht. Ich verwende JGL (eigene Entwicklung für 2D-/3D-Fonts). Was aber bei Fonts stets auffält, ist, dass sie überall ihren Ursprung "links unten" haben. Wenn ich bei meiner Entwicklung einen Text an eine bestimmte Stelle haben will, muss ich auch dort stets 1x Fonthöhe zur Y-Position hinzu zählen.


----------



## Marco13 (18. Apr 2009)

Hatte da neulich schonmal kurz in die API-Doku geschaut, und jetzt nochmal... ich habe TextRenderer noch nicht "richtig" verwendet, und um's zu testen, müßte ich mir erstmal ein KSKB bauen ( 
	

	
	
		
		

		
			





 ) aber mein erster Ansatz wäre, ein TextRenderer.RenderDelegate im Konstruktor zu übergeben, das von TextRenderer.DefaultRenderDelegate erbt, und die "draw"-Methode passend überschreibt, d.h. im übergebenen Graphics praktisch vertikal spiegelt, verschiebt, und nochmal spiegelt... damit müßte das IMHO hinzukriegen sein...


----------



## Evolver (19. Apr 2009)

@Marco13
Ich habe mal ein Testprogramm um das Problem herum erstellt.

```
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.GlyphVector;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;

import com.sun.opengl.util.j2d.TextRenderer;



public class FirstTest implements GLEventListener
{
    public static void main( String[] args )
    {
        new FirstTest();
    }    
    
    private static final int WIDTH = 640;
    private static final int HEIGHT = 480;
    
    private Frame frame;
    private GLCanvas canvas;
    private TextRenderer textRenderer;
    
    
    public FirstTest()
    {
        canvas = new GLCanvas();
        canvas.addGLEventListener( this );
        canvas.setSize( WIDTH, HEIGHT );

    	frame = new Frame( "Simple JOGL Application" );
        frame.add( canvas );
        frame.pack();
        frame.setResizable( false );
        frame.setLocationRelativeTo( null );

        frame.addWindowListener( new WindowAdapter()
	        {
	            @Override
	            public void windowClosing( WindowEvent e )
	            {
	                System.exit( 0 );
	            }
	        });
        
        frame.setVisible( true );
    }

    
    public void init( GLAutoDrawable drawable )
    {
        GL gl = drawable.getGL();

        gl.setSwapInterval( 1 );
        gl.glClearColor( 1.0f, 1.0f, 0.9f, 0.0f );
        gl.glShadeModel( GL.GL_SMOOTH );

        textRenderer = new TextRenderer( new Font( "SansSerif", Font.PLAIN, 30 ),
        								 false, false, new MyRenderDelegate() );
    }

    
    public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height )
    {
        GL gl = drawable.getGL();
        
        gl.glMatrixMode( GL.GL_PROJECTION );
        gl.glLoadIdentity();
        gl.glViewport( 0, 0, WIDTH, HEIGHT );
        gl.glOrtho( 0, WIDTH, HEIGHT, 0, 0, 128 );
    }

    
    public void display( GLAutoDrawable drawable )
    {
        GL gl = drawable.getGL();

        // Clear the drawing area
        gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
        
        textRenderer.beginRendering( drawable.getWidth(), drawable.getHeight() );
        textRenderer.setColor( 0.4f, 0.2f, 0.6f, 0.8f );
        textRenderer.draw( "Blabla", 220, 20 );
        textRenderer.endRendering();
        
        gl.glBegin( GL.GL_QUADS );
          gl.glColor3f( 0.5f, 1.0f, 0.5f );
          gl.glVertex2i( 10, 10 );
          gl.glColor3f( 0.5f, 0.5f, 1.0f );
          gl.glVertex2i( 110, 10 );
          gl.glColor3f( 1.0f, 0.5f, 0.5f );
          gl.glVertex2i( 110, 110 );
          gl.glColor3f( 0.5f, 0.5f, 1.0f );
          gl.glVertex2i( 10, 110 );
        gl.glEnd();

        gl.glFlush();
    }

    
    public void displayChanged( GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged )
    {
    }
}


class MyRenderDelegate extends TextRenderer.DefaultRenderDelegate
{
	@Override
	public void draw( Graphics2D g2d, String str, int x, int y )
	{
		super.draw( g2d, str, x, y );
	}
	

	@Override
	public void drawGlyphVector( Graphics2D g2d, GlyphVector vector, int x, int y )
	{
		super.drawGlyphVector( g2d, vector, x, y );
	}
}
```

Ich habe jetzt schon mal ein bisschen im eigenen RenderDelegate rumgespielt, aber die Ergebnisse waren eher ... naja, nicht der Rede wert.


----------



## Marco13 (19. Apr 2009)

Oh ja, hab's jetzt mal getestet. Da hatte ich beim TextRenderer und dem RenderDelegate einiges mißverstanden (bzw. einiges ging aus der API-Doku nicht eindeutig hervor), aber nach einem Blick in den Quellcode ist einiges klarer. Das RenderDelegate ist nicht dafür da, wofür ich gedacht hatte - das wird wirklich nur verwendet, um einzelne Buchstaben zu zeichnen und in den Cache zu legen (die drawGlyph-Methode wird bei "Blabla" z.B. nur 4 mal aufgerufen). Das eigentliche Rendern liegt im Zusammenspiel mit dem TextRenderer und seiner privaten "Glyph"-Klasse - da kommt man wohl erstmal nicht ran 

Die einzige Möglichkeit, die ich jetzt sehe, ist, das Koordinatensystem per Hand umzurechnen, also nicht 
textRenderer.draw( "Blabla", 220, 40 );
sondern
textRenderer.draw( "Blabla", 220, drawable.getHeight()-40 );
zu schreiben... 

Vielleicht hat noch irgendjemand einen anderen Ansatz, aber ... ich wüßte da jetzt nichts mehr - der TextRenderer ist erschreckend einfach und bequem zu verwenden, aber die einfache API erzwingt ja schon geradezu, dass man die "Innereien" nicht so leicht beeinflussen kann.


----------



## Evolver (20. Apr 2009)

Ja, ich habe mir jetzt einen abgeleiteten TextRenderer geschireben, der die Koordinaten immer enstprechend umrechnet. Dem gebe ich einfach immer die gleichen Koordinaten (left, right, bottom, top) wie dem glOrtho-Aufruf. Das müsste eigentlich passen.


```
public class OrthoTextRenderer extends TextRenderer
{
	private int left;
	private int right;
	private int top;
	private int bottom;
	
	
	public OrthoTextRenderer( Font font )
	{
		super( font );
		setOrthoCoordinates( 0, 0, 0, 0 );
	}
	
	// Anwendungsbeispiel:
	// gl.glOrtho( 0, WIDTH, HEIGHT, 0, 0, 128 );
	// textRenderer.setOrthoCoordinates( 0, WIDTH, HEIGHT, 0 );
	public void setOrthoCoordinates( int left, int right, int bottom, int top )
	{
		this.left = left;
		this.right = right;
		this.bottom = bottom;
		this.top = top;
	}
	
	
	private int getOrthoX( int x )
	{
		if( left<=right )
			return x - left;
		else
			return left - x + right;
	}
	
	
	private int getOrthoY( int y )
	{
		if( bottom<=top )
			return y - bottom;
		else
			return bottom - y + top;
	}

	
	@Override
	public void draw( String text, int x, int y )
	{
		super.draw( text, getOrthoX( x ), getOrthoY( y ) );
	}

	
	@Override
	public void draw( CharSequence text, int x, int y )
	{
		super.draw( text, getOrthoX( x ), getOrthoY( y ) );
	}
}
```


----------



## XyMorgan (22. Apr 2009)

Hi,

die falsche Positionierung des Textes ensteht dadurch, dass der Textrenderer ein
anderes Koordinatensystem verwendet. Der TextRenderer rendert den erzeugten Text
über den TextureRenderer, der wird indirekt über beginnRendering mit Breite und Höhe
versorgt.

Du benutzt bei Deinem Ortho-Koordinatensystem 

0,0 .. Breite,0
.                .
.                .
0,Höhe .. Breite,Höhe

Der TextureRenderer benutzt aber das bei OpenGL eher übliche Koordinatensystem

0,Höhe .. Breite,Höhe
.                .
.                .
0,0 .. Breite,0

Daher ist der 0,0 Bezugspunkt verschoben, bzw. liegt beim TextureRenderer in der linken, unteren Bildschirmecke,
bei Dir in der linken, oberen Bildschirmecke.

Dein Ansatz ist soweit daher also nutzbar, weil Du den Bezugspunkt ja nun umrechnest.
Grundlegend solltest Du aber überlegen, ob Du nicht den Bezugspunkt Deiner Anwendung auch nach unten, links verlegst. Diese Koordinatenprobleme wirst sonst evtl noch öfter bekommen.

bei Dir derzeit:
gl.glOrtho( 0, WIDTH, HEIGHT, 0, 0, 128 );

TextureRenderer benutzt:
gluOrtho2D(0, width, 0, height); 

Ansonsten würde es reichen, wenn Du in der draw-Methode nur die Y-Position umrechnest. Dein Koordinatensystem hat 800 Höhe, und Du willst den Text bei 100 Höhe ausgeben, dann wäre es beim TextureRenderer-Koordinatensystem an der Position 700 also Höhe - YPosition.

//Martin.


----------



## Evolver (27. Apr 2009)

ICh glaube langsam, ich werde mich vom TextRenderer, der so schön einfach its, wieder abwenden. Denn wenn sobald ich z.B. mit glTranslate arbeite, ziehen die Änderungen beim Renderer wieder nichtmher und ich müsste es ebenfalls manuell nachziehen. Das ist zwar keine große Sache, aber langsam nervt das Ding. 

@XyMorgan
Über die Verlegung des Koordinatenursprungs habe ich schon nachgedacht, aber das entscheidet sich erst etwas päter.


----------



## Spacerat (27. Apr 2009)

Ich kann hier ja noch mal meine JOGL-Text-Unterschtützung verlinken. Das Paket im Forum ist zwar nicht mehr das jüngste aber immehin. Bei Bedarf kann ich Interessenten ja eine aktuellere Version zukommen lassen (z.B. per E-Mail). Also hier erstmal der Link.
3D-Fonts mit JOGL


----------

