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: Ich frage mich nun, ob es mir opengl ermöglicht nur einen Ausschnitt davon zu zeichnen / anzuzeigen. In etwa so:
Weiß jemand dazu was? Ich habe schon mit glViewport herum experimentiert, doch dies bewirkt nur einen Skalierungs Effekt. Jedenfalls bei mir.
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)
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)
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ß.
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 network • my 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
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.
Und nun, wenn ich versuche, glTranslatef anzuwenden. Ich schiebe es quasi unter das Fenster:
Code mit glTranslatef:
Code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const int vw = ...
const int vh = ...
glOrtho(0, vw, vh, 0, 1, -1);
glViewport(0, 640 - vh, vw, vh);
glTranslatef(50, 0, 0);
this._vbo.bindTexture(this._tex); /// Binden des Tilesets an den Vertex Buffer
this._vbo.drawArrays(Primitive.Type.TriangleStrip, /// Zeichnen per glDrawArrays
this._vertexCount);
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):
Sofern dies nicht per glOrtho + glViewport lösbar ist, wäre denn dann sowas mit glScissor möglich? Und wenn wie?
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)
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: und der Ausschnitt wandert nach rechts unten:
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
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
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?
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.
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:
// Bei der Initialisierung:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, breite_des_fensters_in_pixel, // sorgt dafuer, dass die Angaben von glTranslatef auch in Pixeln sind
0.0f, hoehe_des_fensters_in_pixel,
1.0f, -1.0f);
// Beim Rendern
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(5.0f, 3.0f, 0.0f);// verschiebt die Szene um 5 Pixel nach rechts und 3 Pixel nach oben
glEnable(GL_SCISSOR_TEST);
glScissor(x+5, y+3, // verschiebt den sichtbaren Ausschnitt um 5 Pixel nach rechts und 3 Pixel nach oben
breite_des_ausschnitts_in_pixel,
hoehe_des_ausschnitts_in_pixel);
// hier das eigentliche Rendern ...
// nachher ggf.
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)
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?
Mitglieder in diesem Forum: 0 Mitglieder und 11 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.