Android schwarzer Bildschirm beim Rendern von Text und Dreiecken

KYL3R

Mitglied
Hallo liebes java-forum.

Ich habe folgendes Problem :

Meine App nutz eine glsurface und dort habe ich als erstes 2 Dreiecke platziert, die auch bewegt werden können, stellen vorerst die Spielfiguren dar.

Nun wollte ich dynamisch veränderbaren Text einbauen, um FPS-counter, Spielernamen, lebenspunkte etc darzustellen.

Ich arbeite immer mit einem Auge auf dieses Tutorial :
link zum Tutorial auf androidpit.de

Ein paar Tests haben jetzt ergeben dass ich nicht Text und Dreiecke gleichzeitig rendern kann.
Entweder Text, oder Dreiecke, aber beides stört sich so sehr, dass ich gar nichts von beidem sehe, sondern nur einen schwarzen Bildschirm.

Hauptproblem (soweit ich das einschätzen kann) ist, dass ich nicht wirklich viel von diesen Befehlen hier verstehe :
Java:
gl.glMatrixMode( GL10.GL_MODELVIEW );
          gl.glLoadIdentity();
          gl.glTranslatef( 100, 100, 0
          gl.glEnable( GL10.GL_TEXTURE_2D );
          gl.glEnable( GL10.GL_BLEND );
          gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );


Ich habe hier mal etwas Code für euch :

in Setup() definier ich den Text:
Java:
font = new Font( gl, activity.getAssets(), "arial.ttf", 16, FontStyle.Plain );
        text = font.newText( gl );
        text.setText( "This is a test string!!" );

In der MainLoopIteration() (wird jedes Frame aufgerufen) passiert folgendes:
Java:
gl.glViewport(0, 0, activity.getViewportWidth(),activity.getViewportHeight());
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		
		updateVerticesPlayer1(); // aktualisiert die Koordinaten der Dreiecke
		updateVerticesPlayer2(); // aktualisiert die Koordinaten der Dreiecke
		
		drawPlayer1(activity, gl); // zeichnet Spieler1, code poste ich weiter unten
		drawPlayer2(activity, gl); // zeichnet Spieler2, code ist wie bei 1 nur andere Farbe...
		
		
                  // Ab hier beginnt der Code für den Text, der auch funktioniert, 
                  // wenn ich drawPlayer [U]nicht[/U] aufrufe.
          gl.glMatrixMode( GL10.GL_PROJECTION );
          gl.glLoadIdentity();
          GLU.gluOrtho2D(gl, 0, activity.getViewportWidth(), 0, activity.getViewportHeight() );
        
          gl.glMatrixMode( GL10.GL_MODELVIEW );
          gl.glLoadIdentity();
          gl.glTranslatef( 100, 100, 0 );
        
          gl.glEnable( GL10.GL_TEXTURE_2D );
          gl.glEnable( GL10.GL_BLEND );
          gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
          text.render();
          gl.glDisable( GL10.GL_TEXTURE_2D );
          gl.glDisable( GL10.GL_BLEND );

hier der Code von DrawPlayer1:
Java:
private void drawPlayer1(GameActivity activity, GL10 gl) {
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesPlayer1);
		gl.glColor4f(1, 0, 1, 1);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
		gl.glLoadIdentity();
	}


Problem äußert sich wie folgt, wenn ich drawPlayer aufrufe(also nicht auskommentiere) und den Text-code auch drin lasse, dann sehe ich ca. 1 Frame die Dreiecke, nicht aber den Text. Danach ist alles schwarz. Keine Fehlermeldung, kein Crash, keine Daten in Log-cat.

Ich schätze einfach, dass sowas wie
Java:
gl.glMatrixMode( GL10.GL_PROJECTION );
einfach etwas verstellt, sodass die Dreiecke nicht mehr sichtbar werden. und gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); macht vllt das gleiche für den Text unmöglich...

Aber ist nur ne wage vermutung...

Ich habe den draw-Aufruf für Player schon an verschiedene Stellen gesetzt, hinter den Text oder mitten rein, überall das selbe Resultat, außer wenns ganz unten ist, dann wars von anfang an


Ich kann ganz gut Programmieren, aber in Android bin ich relativ neu und mit openGL in android arbeite ich jetzt zum aller ersten mal... Ich komme ja prinzipiell gut voran, nur macht mir diese simple Aufgabe "zeichne einen Text auf die Bühne" so große Probleme... Finde unglaublich aufwending, bin mit Flash-actionscript aufgewachsen, da ging sowas in 2 zeilen... aber ist auch ne grafische Scriptsprache und recht unperformant... lassen wir das.

Kann mir einer Helfen ? Erklärungen zu den gl.gl.... einstellungen wären bestimmt hilfreich, vielleicht bin ich auch völlig auf dem Holzweg...
 

Flown

Administrator
Mitarbeiter
Hauptproblem (soweit ich das einschätzen kann) ist, dass ich nicht wirklich viel von diesen Befehlen hier verstehe :
Java:
gl.glMatrixMode( GL10.GL_MODELVIEW );
          gl.glLoadIdentity();
          gl.glTranslatef( 100, 100, 0
          gl.glEnable( GL10.GL_TEXTURE_2D );
          gl.glEnable( GL10.GL_BLEND );
          gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );

Kann mir einer Helfen ? Erklärungen zu den gl.gl.... einstellungen wären bestimmt hilfreich, vielleicht bin ich auch völlig auf dem Holzweg...

Kurz: ich hab jetzt mit OpenGL nur mit C gearbeitet.

Wenn ein Bildschirm schwarz ist, dann deutet meistens etwas darauf, dass die Kamera nicht auf die zu anzeigenden Objekte blickt.

Allgemein:
Also das Tutorial erklärt vieles. Ich würd es mir noch einmal genau durchlesen und verstehen.

Matrizen:
Also die ganzen Transformationen von Objekten in OpenGL wird mit Matrizen/-stacks gelöst. Sie sind einfach und schnell zu berechnen.

Zu den Befehlen:
Java:
gl.glMatrixMode( GL10.GL_MODELVIEW );
Matrizen-Erklärung für die einzelnen MatrixModes.

Java:
gl.glLoadIdentity();
Verwirft die aktuelle Matrix und ersetzt diese mit der Einheitsmatrix

Java:
gl.glTranslatef( 100, 100, 0);
Verschiebt ein Objekt in (x, y, z) Richtung

Java:
gl.glEnable(...);
gl.glDisable(...);
Aktiviert Features von OpenGL so wie Alpha-Blending (
Java:
gl.glEnable( GL10.GL_BLEND);
)

Java:
gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
Gibt nur an welche Alpha-Blending-Funktion verwendet wird. Mehr hier
 

KYL3R

Mitglied
Ich habe noch ein bisschen rumprobiert...


wenn ich es so probiere :
Java:
       drawPlayer1(activity, gl);
		drawPlayer2(activity, gl);
		

          //gl.glMatrixMode( GL10.GL_PROJECTION );
          gl.glLoadIdentity();
          GLU.gluOrtho2D(gl, 0, activity.getViewportWidth(), 0, activity.getViewportHeight() );
        
          gl.glMatrixMode( GL10.GL_MODELVIEW );
          gl.glLoadIdentity();
          //gl.glTranslatef( 100, 100, 0 );
        
          gl.glEnable( GL10.GL_TEXTURE_2D );
          gl.glEnable( GL10.GL_BLEND );
          gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );
          //text.render();
          gl.glDisable( GL10.GL_TEXTURE_2D );
          gl.glDisable( GL10.GL_BLEND );
Dann sehe ich beide dreiecke, aber keinen text.
Wenn ich gl.glMatrixMode wieder "aktiviere" verschwinden beide, wenn ich es auskommentiert lasse und dafür gl.glTranslatef(100,100,0) aktiviere, verschwindet nur das erste.

Wenn ich drawPlayer1 mit drawPlayer2 vertausche, wird spieler 2 zuerst gezeichnet, dann ist nur spieler 1 sichtbar.

Ich schätze jetzt, dass gl.glTranslatef allgemein openGL koordinaten oder so verändert, die im nächsten durchlauf von dem zuerst gezeichneten zwangsläufig verwendet werden, sodass es außerhalb des sichtbaren bereichs landet. Deshalb sind die Dreiecke auch immer nur ca 1 Frame sichtbar, weil sie erst gezeichnet werden, dann der text (der ja leider garnicht sichtbar ist) welcher diese koordinaten "verzaubert" und dann sind sie außerhalb des sichtbereichs.

1 - Was macht gl.glTranslatef ?
2 - Kann ich das nicht "global" auf das gesamte openGP, sondern lokal, also nur für jedes Objekt einzeln aufrufen ? Denn da steht ja nur gl.glTranslatef, nicht auf welches Objekt oder so.
In etwa so wäre es wohl besser :
Java:
zeichneMichDortHin(x = Translatef(100), y = Translatef(230));
oder so .... :D
 
Zuletzt bearbeitet:

KYL3R

Mitglied
Kurze Rückfrage, hab den Beitrag grad überflogen weil ich meinen fast zeitgleich gepostet hatte...

Java:
gl.glTranslatef( 100, 100, 0);
- das verschiebt das Objekt, (100,100,0) ist quasi der verschiebungsvektor... - wenn das in der mainLoopIteration steht, verscheibt sich das Objekt dann jedes Frame um diesen Wert ? Anders gefragt, ist das ein :"bewegeDichUm(Wert)" oder "geheZuPunkt(Wert)" ?
 

Flown

Administrator
Mitarbeiter
Also wenn du immer die selbe Matrix hast und diese nicht push/pop oder mit loadIdentity überschreibst, dann verschiebst du dieses immer um den (x, y, z)-Faktor
 

KYL3R

Mitglied
Ich rufe jetzt sicherheitshalber vor und nach jedem Zeichnen gl.glLoadIdentity(); auf, wirklich verändert hat das auch nichts...

Habe vor dem Zeichnen der Dreiecke mal alle 3 Matrizenmodi aktiviert (alle durchgetestet) , änder auch nicht.

Folgender Code ist die render() Methode, die mit "text" aufgerufen wird:
Java:
public void render( PrimitiveType type, int offset, int numVertices )
        {
                boolean wasDirty = dirty;
                if( dirty )
                        update();
                
                if( this == lastMesh && !wasDirty )
                {
                        gl.glDrawArrays( getPrimitiveType( type ), offset, numVertices );
                        return;
                }
                else
                {
                        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY );                 
                        gl.glDisableClientState(GL10.GL_COLOR_ARRAY );                  
                        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY );                  
                        gl.glDisableClientState(GL10.GL_NORMAL_ARRAY );
                }
                
                gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
                if( globalVBO )
                {
                        ((GL11)gl).glBindBuffer( GL11.GL_ARRAY_BUFFER, vertexHandle );
                        ((GL11)gl).glVertexPointer( 3, GL10.GL_FLOAT, 0, 0 );
                }
                else
                        gl.glVertexPointer( 3, GL10.GL_FLOAT, 0, vertexBuffer );
                
                if( colors != null )
                {
                        gl.glEnableClientState( GL10.GL_COLOR_ARRAY );
                        if( globalVBO )
                        {
                                ((GL11)gl).glBindBuffer( GL11.GL_ARRAY_BUFFER, colorHandle );
                                ((GL11)gl).glColorPointer( 4, GL10.GL_FLOAT, 0, 0 );
                        }
                        else
                                gl.glColorPointer( 4, GL10.GL_FLOAT, 0, colorBuffer );
                }
                
                if( texCoords != null )
                {
                        gl.glEnableClientState( GL10.GL_TEXTURE_COORD_ARRAY );
                        if( globalVBO )
                        {
                                ((GL11)gl).glBindBuffer( GL11.GL_ARRAY_BUFFER, texHandle );
                                ((GL11)gl).glTexCoordPointer( 2, GL10.GL_FLOAT, 0, 0 );
                        }
                        else
                                gl.glTexCoordPointer( 2, GL10.GL_FLOAT, 0, texCoordBuffer );
                }
                
                if( normals != null )
                {
                        gl.glEnableClientState( GL10.GL_NORMAL_ARRAY );
                        if( globalVBO )
                        {
                                ((GL11)gl).glBindBuffer( GL11.GL_ARRAY_BUFFER, normalHandle );
                                ((GL11)gl).glNormalPointer( GL10.GL_FLOAT, 0, 0 );
                        }
                        else
                                gl.glNormalPointer( GL10.GL_FLOAT, 0, normalBuffer );
                }
                
                gl.glDrawArrays( getPrimitiveType( type ), offset, numVertices );
                lastMesh = this;
        }

Hier wird auch viel an gl verstellt, Enable oder glDisableClientState, muss ich das vielleicht irgendwie wieder zurücksetzen nach dem zeichnen ?

Komisch ist nach wie vor, dass ich nichts sehe, weder Text noch Dreiecke...
 

Flown

Administrator
Mitarbeiter
Also wie schon vorhin gesagt, ich habe mit openGL nur mit c/c++ gearbeitet, darum kann ich jetzt nicht sagen, was du in dem render() machst.

Um das Missverständnis aus dem Weg zu räumen

Java:
glLoadIdentity();
Löscht dir deine Matrix (somit alle Kameraeinstellungen, Positionen der Objekte). Sowas macht man mit MatrixStacks(push/pop).

Ich würde dir dringend raten einige Tutorials und Grundlagen von openGL durchzulesen und nicht einfach "machen".

Man sollte verstehen wie die Graphics Pipeline funktioniert, wie man die Kameraposition an welcher Pipeline Position ändert. Wie man Objekte definiert(e.g. Dreiecke), wie man sie färbt, positioniert, dreht, skaliert, ... . Wichtig ist auch noch die Projection-Mode und ModelView-Mode Matrix zu verstehen. Wichtig auch zu verstehen, dass openGL eine Statemaschine ist (darum auch immer glEnable/glDisable). Danach noch wie man mit push/pop-Matrix arbeitet.

Danach geht man ans animieren.

Sorry das ich sonst nicht weiterhelfen kann.
 

KYL3R

Mitglied
Hallo, erneut :)

Ich hatte mich vorerst auf andere Dinge konzentriert, jetzt kam folgendes Problem :
Touch Koordinaten (die man abfragt) bekam ich als ints, in pixeln. bei mir: 480x800
Jetzt hatte ich aber ein Koordinatensystem was von -1 bis 1 geht (auf jeder Skala, x und z)

Meine Spielerkoordinaten waren dann so in etwa : (-0.8,0.2) und die Geschwindigkeiten waren im Bereich von 0.002. Lief soweit gut. Nur etwas Blöd wenn ich meine Buttons zeichnen möchte, die Abgefragten Positionen stimmen dann gar nicht mit dem Button-mesh überein.

Ich dachte ich könnte das einfach umrechnen, wenn der Bildschrim (querformat) 800pixel breit ist, und meine Position zwischen -1 und 1 liegt, geht das theoretisch so :
PosInPixeln:(POS/2)-1*800
-> Aus -1 bis 1 wird dann erstmal 0 bis 2, dann ziehe ich 1 ab und rechne * 800, so müsste proportional die passende pixel-koordinaten bekommen. Irgendwas lief da schief, also las ich nochmal in dem Tutorial, versuchte dann GLU.Ortho2D richtig einzurichten. Im Tutorial stand nämlich, dass OpenGl hier ein "pixel-basiertes" koordinatensystem bastelt.

Vorerst hatte ich hier auch einen schwarzen Bildschirm, jedoch nur weil die ganzen Werte (position, breite) alles unter 1 waren. bei 800 Pixeln fällt es einem schwer da noch was zu sehen.

Ich änderte dann die Positionen und breiten auf Werte im hunderterbereich und sah plötzlich wieder meine Spieler und das Steuerkreuz etc.

Dann war der Text ein leichtes.


Moral ist also, dass man für Text besser ein 2Dimensionales orthogonales Koordinatensystem nimmt und darauf achtet, dass die Positionswerte in realistischen Bereichen liegen.

Trotzdem vielen Dank an alle die mitgeholfen haben. :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Bildschirm Nutzung Überwachen der App Nutzer ink. was angeklickt wird Android & Cross-Platform Mobile Apps 35
L Android Bildschirm bleibt dunkel nach neustarten der App nach betätigen des Home-Buttons Android & Cross-Platform Mobile Apps 3
J Displaygröße ermitteln und bildschirm anpassen Android & Cross-Platform Mobile Apps 3
W Bildschirm gesperrt - kein Broadcast? Android & Cross-Platform Mobile Apps 2
G Zugriff auf den gesamten Bildschirm bei PDAs Android & Cross-Platform Mobile Apps 8
R Android Löschfunktion beim Wischen Android & Cross-Platform Mobile Apps 10
W Rand ändern beim ImageView bei Picasso Android & Cross-Platform Mobile Apps 1
Arif Android Android Studio: Fehler beim Einbinden fremder Bibliothek? Android & Cross-Platform Mobile Apps 2
L App stürtzt ab beim öffnen Android & Cross-Platform Mobile Apps 1
JavaWolf165 Android Fehler beim Speichern/Downloaden einer Datei Android & Cross-Platform Mobile Apps 2
S Android Probleme beim Verbinden mit einer HTTPS Seite Android & Cross-Platform Mobile Apps 4
M Android Fehler beim Parsen. Android & Cross-Platform Mobile Apps 29
V Android Fehlermeldung beim Öffnen von Eclipse nach Installation der Android Erweiterung Android & Cross-Platform Mobile Apps 4
M Error beim drücken der Zurück-Taste am Handy Android & Cross-Platform Mobile Apps 2
S Fehler beim Textdatei einlesen!? Android & Cross-Platform Mobile Apps 7
A Fehlermeldung beim ändern der ViewGroup. Android & Cross-Platform Mobile Apps 6
H Buttons färben sich mit, beim Hintergrund ändern Android & Cross-Platform Mobile Apps 3
A Mehrere Fehler beim Compilieren Android & Cross-Platform Mobile Apps 4
G Problem beim Rendern von 3D-Objekt Android & Cross-Platform Mobile Apps 0
L Android OutOfMemory beim erneuten Starten der App Android & Cross-Platform Mobile Apps 2
N Android Retain Dialog verschwindet beim drehen Android & Cross-Platform Mobile Apps 4
B Android GameLoopThread stürzt beim 2ten start der App ab? Android & Cross-Platform Mobile Apps 4
K Nullpointer beim Löschen von Datenbankeintrag, je nachdem wo der Befehl steht Android & Cross-Platform Mobile Apps 5
S Java ME Exception beim Abspielen von Musik Android & Cross-Platform Mobile Apps 6
G Fehler beim Import "Invalid project description" Android & Cross-Platform Mobile Apps 2
G unterschiedliches Verhalten beim Installieren des App auf dem Smartphone Android & Cross-Platform Mobile Apps 3
DaniSahne96 Problem beim Appdebuggen auf Smartphone Android & Cross-Platform Mobile Apps 3
P Android Problem beim Widget - Denkfehler ? Android & Cross-Platform Mobile Apps 2
A Fehler beim Starten eines Intents - alles in einer Klasse funktioniert... Android & Cross-Platform Mobile Apps 4
J Android Verhalten beim Hinzufügen neuer Views? Android & Cross-Platform Mobile Apps 6
S Android Fehler beim Anzeigen meines Apps auf Galaxy Tab Android & Cross-Platform Mobile Apps 4
G Beziehung von THIS beim Imageadapter und AsyncTask Android & Cross-Platform Mobile Apps 7
V [Java] und [JavaME] ClientServer StreamConnection . Problem beim lesen / schreiben Android & Cross-Platform Mobile Apps 2
R Ein Problem beim ausführen von folgendem Quelltext Android & Cross-Platform Mobile Apps 11
N Error in HTTP operation beim KXML parsen Android & Cross-Platform Mobile Apps 7
A Problem beim Subtrahieren eines Double von einem Double Android & Cross-Platform Mobile Apps 5
G fehldermeldung beim klicken auf "build" Android & Cross-Platform Mobile Apps 8
L SecurityException beim lesen/schreiben eine Datei Android & Cross-Platform Mobile Apps 7
F Problem beim Erstellen der Jar File Android & Cross-Platform Mobile Apps 4
S createPlayer beim Entwickeln Android & Cross-Platform Mobile Apps 6

Ähnliche Java Themen

Neue Themen


Oben