Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 04, 2025 04:07

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Viewport einer TileMap
BeitragVerfasst: Mi Sep 11, 2013 19:15 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Hallo. Ich zeichne derzeit eine TileMap mittels glDrawArrays und einem Tileset. Die sieht derzeit so aus:
Bild
Ich frage mich nun, ob es mir opengl ermöglicht nur einen Ausschnitt davon zu zeichnen / anzuzeigen.
In etwa so:
Bild

Weiß jemand dazu was? Ich habe schon mit glViewport herum experimentiert, doch dies bewirkt nur einen Skalierungs Effekt. Jedenfalls bei mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Mi Sep 11, 2013 19:59 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Du zeichnest alles in 2D, oder? Dann kannst du den betrachteten Bereich einfach mit glOrtho einstellen. Achte darauf, dass du beim Aufruf von glOrtho nicht die ModelView-, sondern die Projectionmatrix bearbeitest (glMatrixMode).

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Mi Sep 11, 2013 20:07 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ich habe es jetzt mit dieser Methode hinbekommen:
Code:
  1.  
  2. int[4] vport;
  3. glGetIntegerv(GL_VIEWPORT, &vport[0]);
  4. glViewport(0, vport[3] - 100, 100, 100);
  5. glScalef(vport[2] / 100f, vport[3] / 100f, 0f);
  6.  


Aber ich werde mal deine probieren.
Das wäre dann:
Code:
  1.  
  2. glMatrixMode(GL_PROJECTION);
  3. glOrtho(0, 100, 100, 0, 1, -1);
  4.  

oder?

edit:
Damit:
Code:
  1.  
  2. glLoadIdentity();
  3. glOrtho(0, 100, 100, 0, 1, -1);
  4.  


Wird der Ausschnitt zwar korrekt bestimmt, jedoch füllt er das komplette Fenster aus.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Mi Sep 11, 2013 20:19 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
So funktioniert es korrekt:
Code:
  1.  
  2. int[4] vport;
  3. glGetIntegerv(GL_VIEWPORT, &vport[0]);
  4. glLoadIdentity();
  5. glOrtho(0, 100, 100, 0, 1, -1);
  6. glViewport(0, vport[3] - 100, 100, 100);
  7.  


Welche beider Varianten ist nun vorzuziehen? Und gibt es noch andere, vllt. sogar performantere?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 08:13 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Oh, da habe ich dich wohl missverstanden. Wenn du nicht den Ausschnitt auf das ganze Fenster vergrößern möchtest, wäre glScissor wohl das richtige für dich. glViewport sollte man eigentlich so selten wie möglich aufrufen, da die Grafikkarte u.U. den Speicher für den Front- und Backbuffer neu alloziert. Wenn du den Ausschnitt dann noch an eine bestimmte Stelle haben möchtest (z.B. rechts unten, wie es scheinbar in deinem Code gemacht wird), kannst du ihn mit glTranslatef verschieben und glScissor die entsprechenden Parameter übergeben.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 08:40 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Und wie würde der Code aussehen? Denn leider scheint glScissor mekrwürdig zu funktionieren.
Meine Map ist 160px breit und hoch. Mein Fenster ist 1024x640 groß.
Code:
  1. glScissor(0, 0, 140, 500);

produziert dieses Bild:
Bild

und
Code:
  1. glScissor(0, 0, 140, 600);

dieses:
Bild

Wie lässt sich das erklären?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 09:57 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
glScissor misst von unten links und nimmt die Argumente x, y, width und height.

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 20:10 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Sofern ich mich für die glOrtho + glViewport Methode entschieden habe, ist es möglich, diesen Ausschnitt danach/davor per glTranslatef und/oder glRotatef zu beeinflussen?
Wenn ich glTranslatef probieren, dann bewege ich den Ausschnitt logischerweise nur in seinem neuen, eigenen Viewport und 'schiebe' den Ausschnitt dabei quasi aus dem sichtbaren Fenster, bzw. darunter. Wie kann ich also glTranslatef auf diesen Ausschnitt anwenden?

Zur Verdeutlichung noch zwei Bilder:
Hier einmal der Ausschnitt, natürlich an 0|0 weil ich den Ursprung von Viewport bzw glOrtho dahin gesetzt haben.
Bild

Und nun, wenn ich versuche, glTranslatef anzuwenden. Ich schiebe es quasi unter das Fenster:
Bild

Code mit glTranslatef:
Code:
  1.  
  2. glMatrixMode(GL_PROJECTION);
  3. glLoadIdentity();
  4.  
  5. const int vw = ...
  6. const int vh = ...
  7.  
  8. glOrtho(0, vw, vh, 0, 1, -1);
  9. glViewport(0, 640 - vh, vw, vh);
  10.  
  11. glTranslatef(50, 0, 0);
  12.  
  13. this._vbo.bindTexture(this._tex); /// Binden des Tilesets an den Vertex Buffer
  14. this._vbo.drawArrays(Primitive.Type.TriangleStrip, /// Zeichnen per glDrawArrays
  15. this._vertexCount);
  16.  


Ich könnte natürlich auch den Ursprung von glOrtho anpassen (oder von glViewport), aber ich würde gerne wissen, ob das auch mit glTranslate geht.
Dies ist auch wichtig, um zu wissen, wie ich glRotatef anwenden, denn ansonsten drehe ich den Ausschnitt ja auch im selben, kleinen, neuen Ausschnitt und bekomme nicht alles zu sehen.
Ein Beispiel mit glRotatef(45, 0, 0, 1f):
Bild

Sofern dies nicht per glOrtho + glViewport lösbar ist, wäre denn dann sowas mit glScissor möglich? Und wenn wie?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 20:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
rswhite hat geschrieben:
Sofern ich mich für die glOrtho + glViewport Methode entschieden habe, ist es möglich, diesen Ausschnitt danach/davor per glTranslatef und/oder glRotatef zu beeinflussen?
Wenn ich glTranslatef probieren, dann bewege ich den Ausschnitt logischerweise nur in seinem neuen, eigenen Viewport und 'schiebe' den Ausschnitt dabei quasi aus dem sichtbaren Fenster, bzw. darunter. Wie kann ich also glTranslatef auf diesen Ausschnitt anwenden?

glTranslatef und glRotatef ändern nur gerade mit glMatrixMode ausgewählte Matrix. Alle Vertices, die du renderst, werden mit der Matrix / den Matrizen multipliziert. Die Parameter von glViewport und glScissor werden in keiner Weise von irgendeiner Matrix beeinflusst. Folglich musst du die Verschiebung zu Fuß erledigen. In deinem Beispiel, wo du den Kartenausschnitt nach rechts verschieben willst, muss du also den entsprechenden Wert auf den Parameter x aufaddieren.

glViewport und glScissor beschreiben immer Rechtecke, deren Seiten parallel zu denen des Bildschirms sind. Rotieren kannst du diese nicht. Wenn du eine beliebige Form als "Schablone" verwenden willst, fällt mir momentan nur der Stencil-Buffer als Möglichkeit ein. Das funktioniert dann so, dass du erst die gewünschte Form renderst, dabei aber nicht den Farbpuffer anrührst, sondern nur die entsprechenden Bits im Stencil-Buffer markierst. Danach renderst du im zweiten Pass, und stellst dabei ein, dass nur die Pixel gerendert werden sollen, die du vorher im Stencil-Buffer markiert hast.

Mit dem Stencil-Buffer habe ich selbst noch nie etwas unter OpenGL gemacht, aber im Wiki steht denke ich, welche Funktionen man dazu braucht.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 21:06 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Also ist es nicht so einfach möglich, nur einen Teil einer TileMap/eines Shapes (eine TileMap ist ja praktisch nichts anderes) zu zeichnen und diesen Teil akkurat zu rotieren?

Angenommen ich möchte zwar die gesamte Größe der Map darstellen, aber alles bis auf einen kleinen Ausschnitt schwarz einfärben. Dann möchte ich, dass nur dieser kleine Ausschnitt die TileMap, die darunter liegt, zeigt und ich diesen Ausschnitt auch bewegen kann.

Bildhaft ausgedrückt:
Der hellere Bereich ist mein Ausschnitt (derzeit zentriert), das dunklere die verdeckte Karte:
Bild
und der Ausschnitt wandert nach rechts unten:
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 21:34 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Du kannst natürlich die Map drehen wie du willst, aber der Umriss des sichtbaren Bereiches wird immer eine am Bildschirm ausgerichtete Box sein.

Das Abdunkeln kannst du mit (multiplikativem) Blending erreichen. Dazu muss du mit aktiviertem Alpha-Blending 4 sich nicht überlappende Quads um den hellen Bereich herum zeichnen. Bevor du nach weiteren Details zum Blending fragst, solltest du auf jeden Fall Tutorial_Lektion_7 und glBlendFunc gelesen haben. Hier im Forum wurden auch schon tausend Sachen über Blending gefragt. Wahrscheinlich hast du nach der Lektüre immer noch Fragen, aber die häufigsten sollten dann schonmal rausgefiltert sein :mrgreen:

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 21:40 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Ich hatte gehofft, es gibt einen einfachen Weg, nur den Ausschnitt zu zeichnen und den Rest außen vor zu lassen (oder eben schwarz, abgedunkelt ist nur Ästhetik). Gibt es da nichts einfaches? Ich könnte die TileMap dann ja drehen wie ich will, die Box würde den korrekten Ausschnitt zeigen.
Gibt es da nichts außer 4 Rechtecke zu zeichnen?

edit:
So etwas z.B.:
http://www.sfml-dev.org/tutorials/2.1/g ... -is-viewed
Dort wird nur ein Ausschnitt gezeichnet, der Rest ist schwarz bzw wird nicht gezeichnet/angezeigt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Do Sep 12, 2013 23:30 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
glAwesome hat geschrieben:
Wenn du den Ausschnitt dann noch an eine bestimmte Stelle haben möchtest (z.B. rechts unten, wie es scheinbar in deinem Code gemacht wird), kannst du ihn mit glTranslatef verschieben und glScissor die entsprechenden Parameter übergeben.

Das klingt so, als könnte ich glScissor mit glTranslatef verwenden. :?:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Fr Sep 13, 2013 08:54 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Also nur einen Ausschnitt zeichnen und den Rest schwarz zu lassen, geht wie gesagt ziemlich einfach mit glScissor.

rswhite hat geschrieben:
glAwesome hat geschrieben:
Wenn du den Ausschnitt dann noch an eine bestimmte Stelle haben möchtest (z.B. rechts unten, wie es scheinbar in deinem Code gemacht wird), kannst du ihn mit glTranslatef verschieben und glScissor die entsprechenden Parameter übergeben.

Das klingt so, als könnte ich glScissor mit glTranslatef verwenden. :?:
Mit glTranslatef verschiebst du die Szene. Das hat natürlich die Folge, dass du den gewünschten Ausschnitt aus dem sichtbaren Bereich rausschiebst, wie du ja selbst schon festgestellt hast. Wenn du also möchtest, dass sich der nicht-schwarze Bereich im Fenster mitbewegt, musst du die Parameter x und y von glScissor entsprechend anpassen.

Also mal ein Code-Beispiel:
Code:
  1. // Bei der Initialisierung:
  2. glMatrixMode(GL_PROJECTION);
  3. glLoadIdentity();
  4. glOrtho(0.0f, breite_des_fensters_in_pixel, // sorgt dafuer, dass die Angaben von glTranslatef auch in Pixeln sind
  5.         0.0f, hoehe_des_fensters_in_pixel,
  6.         1.0f, -1.0f);
  7.  
  8. // Beim Rendern
  9. glMatrixMode(GL_MODELVIEW);
  10. glLoadIdentity();
  11. glTranslatef(5.0f, 3.0f, 0.0f);  // verschiebt die Szene um 5 Pixel nach rechts und 3 Pixel nach oben
  12. glEnable(GL_SCISSOR_TEST);
  13. glScissor(x+5,  y+3,  // verschiebt den sichtbaren Ausschnitt um 5 Pixel nach rechts und 3 Pixel nach oben
  14.           breite_des_ausschnitts_in_pixel,
  15.           hoehe_des_ausschnitts_in_pixel);
  16.  
  17. // hier das eigentliche Rendern ...
  18.  
  19. // nachher ggf.
  20. glDisable(GL_SCISSOR_TEST);

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Viewport einer TileMap
BeitragVerfasst: Fr Sep 13, 2013 09:37 
Offline
DGL Member

Registriert: Di Dez 13, 2011 19:14
Beiträge: 166
Wohnort: Hamburg / Mölln
Programmiersprache: D
Mal mein Render Code:
Code:
  1.  
  2. glDisable(GL_BLEND);
  3.        
  4. glPushMatrix();
  5. scope(exit) glPopMatrix();
  6.  
  7. glMatrixMode(GL_MODELVIEW);
  8. glLoadIdentity();
  9. glTranslatef(100f, 3f, 0f);
  10.  
  11. glEnable(GL_SCISSOR_TEST);
  12. scope(exit) glDisable(GL_SCISSOR_TEST);
  13.  
  14. glScissor(50, 500, 100, 100);
  15.  
  16. this._vbo.bindTexture(this._tex);
  17. this._vbo.drawArrays(Primitive.Type.TriangleStrip,
  18.                      this._vertexCount);
  19.  


Das glTranslatef bewirkt wieder nur, dass die Szene unter das restliche Fenster geschoben wird, wenn ich es zu groß mache. Eben das wollte ich wenn möglich vermeiden.
Alles was mir scheinbar bleibt, ist per glOrtho neue x und y Koordinaten für die Verschiebung zu setzen, oder?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]