OpenGL: Problem mit Matrix-Stacks



  • hallo zusammen,

    ich bin neu hier und versuche mich derzeit, so als hobby, in der spiele- bzw. demoprogrammierung.

    ich melde mich hier, da ich ein problem mit OpenGL in C habe. um genau zu sein, programmiere ich grad eine kleine demo mit zwei fahrenden zügen. das klappt auch bisher wunderbar. beide fahren ihre vorgegebene route, sprich schienen, entlang.

    bei der integration der umwelt in meine kleine demo bin ich auf ein unerwartetes problem gestossen. und zwar möchte ich einen kleinen text mit einem weißen hintergrund an den lokomotiven beider züge "befestigen". beide lokomotiven haben ihr eigenes bewegtes koordinatensystem. ich kann nun mit hilfe des OpenGL befehls "glutBitmapCharacter" ganz einfach einen beliebigen text in den ursprung des lokomotiven-koordinatensystem legen. das funktioniert auch wunderbar. egal wie die lokomotive sich bewegt der text ist immer korrekt und orthogonal zum betrachter ausgerichtet.

    hier habe ich mal den code, der das beschreibt:

    void draw_text(char *string, double  gl_para[])
    {
    	glClear(GL_DEPTH_BUFFER_BIT);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    	glLoadMatrixd(gl_para);					// Load opengl matrix
    
    	glColor3f(1.0, 0.0, 0.0);				// Set text color to red
    
    	glRasterPos2f(0.0, 0.0);
    	for (i=0; i<(int)strlen(string); i++)
    	{
    		if(string[i] != '\n' )
    		{
    			glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, string[i]);
    		}
    	}
    }
    

    "gl_para" ist hierbei mein lokomotiven-koordinatensystem.

    den weißen hintergrund habe ich mit einem weißen polygon realisiert. dieses polygon soll in den ursprung des lokomotiven-koordinatensystem gesetzt werden und darauf dann der text geschrieben werden. nur dummerweise funktioniert dies nur im: glMatrixMode(GL_PROJECTION);

    hier der erweiterte code:

    void draw_text(char *string, double  gl_para[])
    {
    	glClear(GL_DEPTH_BUFFER_BIT);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    
    //	glLoadMatrixd(gl_para);					// Load opengl matrix
    
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    
    	glColor3f(1.0, 1.0, 1.0);				// White polygon background
    	glBegin(GL_TRIANGLE_STRIP);				// Draw polygon
    		glVertex2f(0.0, 0.20);
    		glVertex2f(0.0, 0.0);
    		glVertex2f(0.5, 0.2);
    		glVertex2f(0.5, 0.0);
    	glEnd();
    
    	glColor3f(1.0, 0.0, 0.0);				// Set text color to red
    	glRasterPos2f(0.1, 0.1);
    	for (i=0; i<(int)strlen(string); i++)
    	{
    		if(string[i] != '\n' )
    		{
    			glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, string[i]);
    		}
    	}
    }
    

    sobald ich mein eigenes koordinatensystem angebe, stellt er mir dieses prolygon nicht mehr dar. deshalb ist der glLoadMatrixd(gl_para); befehl hier auch auskommentiert. ich bin jetzt seit ein paar tagen dabei und stehe sprichwörtlich auf dem schlauch. ich hätte nicht gedacht, dass die 2D aufgaben so verwirrend mit OpenGL sein können. mein lokomotiven-koordinatensystem ist soweit korrekt. das problem muss irgendwo bei den matrix stacks liegen, aber ich kann nicht erkennen wo genau.

    vielleicht habt ihr ja eine idee wie ich meine obige funktion ändern müsste damit dies funktioniert.

    ich habe per suche leider keine passende antwort zu meinem problem gefunden, von daher hoffe ich ihr könnt mir weiterhelfen 🙂

    gruß
    salo



  • Ich verstehe dein Problem nicht so ganz. Geht jetzt die obere Funktion und die zweite nicht?

    gl_para ist doch sicherlich GL_MODELVIEW und nicht GL_PROJECTION, oder? Dann ist klar warum Du das Polygon nicht sehen kannst (in der zweiten Funktion).

    Vielleicht könnte ein Screenshot dein Problem ja eher verdeutlichen...



  • ja richtig so ist es. die erste funktion, ohne weißes polygon als hintergrund hinter dem text, funktioniert einwandfrei.

    die zweite funktion, mit dem weißen polygon als hintergrund, funktioniert leider nicht.

    gl_para basiert auf GL_MODELVIEW, das ist richtig. aber das problem ist, dass das polygon nicht angezeigt wird wenn ich den GL_MODELVIEW stack auswähle und ich nicht verstehe warum 😞

    ein screenshot kann ich so leider nicht zeigen, da ich das komplette programm auseinandergenommen hab und derzeit gar nix funktioniert, um eben dieses problem zu verstehen.



  • Na, das ist doch schon mal was, wenn die erste Funktion geht. 😉

    Du vermengst nur Bildschirm 2D-Koordinaten mit 3D-Koordinaten.

    glutBitmapCharacter ist 2D....

    ...
    glBegin(GL_TRIANGLE_STRIP);                // Draw polygon
      glVertex2f(0.0, 0.20);
      glVertex2f(0.0, 0.0);
      glVertex2f(0.5, 0.2);
      glVertex2f(0.5, 0.0);
    glEnd();
    ...
    

    Der Code-Teil passt dann aber nicht dazu, da Du hier viel zu klein skalierst.
    (Abhängig ist das Ganze evtl. noch von der verwendeten Projektionsmatrix bzw. vom Viewport).

    Versuche das Polygon mal größer zu zeichnen.

    Es handelt sich doch außerdem um ein Rechteck, warum nimmst Du dann nicht ein GL_QUAD dafür?



  • GL_TRIANGLE_STRIP hatte ich nur drin, um auszuschließen, dass das problem evtl daran lag. aber du hast recht, ich hatte wirklich viel zu klein skaliert. jetzt hab ich zumindest das polygon mit dem text.

    nur stimmt die ausrichtung des polygons noch nicht. es orientiert sich an dem koordinatensystem der lokomotive. steht die lokomotive schräg, so ist das polygon ebenfalls schräg. der text jedoch wird korrekt dargestellt. also egal welche lage und position die lokomotive hat, der text steht immer aufrecht und das weiße polygon entsprechend schräg.

    hab das mal aufgezeichnet:
    http://img514.imageshack.us/img514/6530/texta.jpg

    wie bekomm ich das polygon jetzt dazu, dass es entsprechend dem text ausgerichtet wird?

    ich bin noch relativ neu was die OpenGL programmierung begrifft. habe bisher nur mit 3D objekten herumgespielt. dank diverserer tutorials findet man sich da recht schnell zurecht. aber 2D objekte in einen 3D raum zu platzieren hatte ich bisher noch nicht gemacht. habe mir das wesentlich einfacher vorgestellt 🙂



  • "...aber 2D objekte in einen 3D raum zu platzieren hatte ich bisher noch nicht gemacht..."
    Genau hier ist Dein Problem, denn es ist genau andersrum. Die 3D-Position des Textes wird auf den Bildschirm projiziert (2D). Im Endeffekt hast du nur einen dimensionslosen Punkt, welcher aus den 3D-Koordinaten richtig auf den Bildschirm projiziert wird. Ein Polygon hat aber auch eine Richtung und Ausdehnung (Ich hoffe Du verstehst was ich meine 😉 ).

    Ich weiß jetzt nicht wie Dein Programm genau aufgebaut ist, aber Du könntest es auf zwei Wege lösen:

    1. Du merkst Dir die 2D-Position, auf die der Text im Bildschirm aus dem 3D-Raum projiziert wird, und gehst in den 2D-Modus (glOrtho) und zeichnest das Polygon dort.

    2. Du kippst den Text zurück. Dazu musst Du den Kippwinkel berechnen.

    Bei beiden Lösungen kommt es darauf an, wie Dein Programm im Detail realisiert ist
    (Kamera mit glRotate und glTranslate, gluPerspective oder viewport etc. ?!).
    Kennst Du den Winkel, so ist Option 2 Deine Lösung. Kennst Du ihn nicht, dann Option 1.

    Gruß
    Trooper



  • ach so ist das. das erklärt so manches.

    das aktuelle programm sieht so aus:

    void draw_text(char *string, double  gl_para[])
    {
    	glMatrixMode(GL_PROJECTION);			// Select The Projection Matrix
    	glPushMatrix();
    	glLoadIdentity();
    	glOrtho(0, xsize, 0, ysize, -1, 1);
    
    	glMatrixMode(GL_MODELVIEW);	
    	glPushMatrix();
    	glLoadIdentity();
    
    	glTranslated(0.0, 0.0, 0.0);
    
    	// draw a white polygon
    	glColor3f(1.0, 1.0, 1.0);
    	glBegin(GL_TRIANGLE_STRIP);
    		glVertex2f(0.0, 20.0);
    		glVertex2f(0.0, 0.0);
    		glVertex2f(100.0, 20.0);
    		glVertex2f(100.0, 0.0);
    	glEnd();
    
    	glColor3f(1.0, 0.0, 0.0);				// Set text color to red
    	glRasterPos2f(0.1, 0.1);
    	for (i=0; i<(int)strlen(string); i++)
    	{
    		if(string[i] != '\n' )
    		{
    			glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, string[i]);
    		}
    	}
    
    	glPopMatrix();
    }
    

    da ich den drehwinkel nicht kenne, würde ich option 1, die du vorgeschlagen hast, nehmen. ich habe in den 2D-Modus umgeschaltet und das polygon dort gezeichnet. funktioniert soweit. jedoch kann ich die 2D-Position, auf die der text auf den bildschirm aus dem 3D-Raum projiziert wird, nicht ermitteln. es wäre hilfreich wenn ich wüsste wie glutBitmapCharacter intern arbeitet, so könnte ich den internen vorgang von dem befehl einfach kopieren und auf mein polygon per "glTranslated" anwenden, aber so bin ich doch etwas ratlos.



  • Warum kennst Du den Drehwinkel nicht? Wie ist denn Deine Kamera verwirklicht?
    Für das Programm musst Du gar nicht wissen wie glutBitmapCharacter intern arbeitet. Die Funktion zeichnet einfach einen Text ab der angegebenen Position (glRasterPos2f). Auslesen kann man die Werte auch über GL_CURRENT_RASTER_POSITION.

    Aber das ist alles nicht nötig, da Du meiner Meinung nach die Matrizen durcheinander haust. 😉

    Mit der Funktion alleine kann ich dein Problem jedenfalls nicht lösen...



  • Ist das Problem gelöst oder hast Du aufgegeben? 🙂



  • sorry das ich so spät antworte.

    das problem ist leider noch nicht ganz gelöst. ich habe das problem gefunden und, wie du auch richtig erkannt hast, hab ich die matrizen durcheinandergehauen. ich denke ich weiß nun was ich verändern muss damit das ganze funktioniert, kann es aber nocht nicht testen. das ganze ist nur ein hobby, daher hab ich unter der woche nicht soviel zeit zum ausprobieren. ich hoffe, dass ich es am wochenende hinbekomme. falls nicht meld ich mich wieder 😃


Anmelden zum Antworten