Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

OpenGL: Textur auf Multipolygon Objekte

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Bibliotheken
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
schildron



Anmeldungsdatum: 25.08.2008
Beiträge: 86

BeitragVerfasst am: 04.08.2010, 14:25    Titel: OpenGL: Textur auf Multipolygon Objekte Antworten mit Zitat

Hallo!

Mein Problem ist dass ich mit
Code:
GL_TRIANGLE_FAN

eine Linie mit abgerunden Enden erstelle. Dies ist kein Problem.

Wenn ich das gesamte Objekt mit einer Textur bedecken will, muss ich TexturKoordinaten angeben, sonst ist das Objekt einfärbig.

Leider weiß ich nicht wo ich diese im Code angeben soll. Ich bitte um Hilfe.
Derzeit versuche ich die Texturkoordinaten mit dem Befehl
Code:
glTexCoord2d

anzugeben.

Code:

'Punkt1X / Punkt1Y = StartPunkt
'Punkt2X / Punkt2Y = ZielPunkt
'Steigung = Steigung im Bezug zur Waagrechte

glEnable GL_TEXTURE_2D
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
If Mapdatei(MapZeilenCounter) = "Plattform.static" Then
   If gefahr = "white" Then
      glBindTexture GL_TEXTURE_2D, Wand_white
   ElseIf gefahr = "blue" Then
      glBindTexture GL_TEXTURE_2D, Wand_blue
   ElseIf gefahr = "red" Then
      glBindTexture GL_TEXTURE_2D, Wand_red
   EndIf
EndIf
'----------------------
'Plattformen rendern
'----------------------
Dim As Single Winkel,X,Y

glBegin GL_TRIANGLE_FAN
For Counter As Integer = 0 To 20
   Winkel = Steigung + 90 + Counter*18
   Winkel = Winkel * pi/180
   '' In Karthesisches System umwandeln
   X = dicke/2 * Cos(Winkel)
   Y = dicke/2 * Sin(Winkel)

   If Counter < 10 Then
      glVertex3f  Punkt1X + X, Punkt1Y + Y, -6.0
   ElseIf Counter = 10 then
      glVertex3f  Punkt1X + X, Punkt1Y + Y, -6.0
      glVertex3f  Punkt2X + X, Punkt2Y + Y, -6.0
   ElseIf Counter > 10 Then
      glVertex3f  Punkt2X + X, Punkt2Y + Y, -6.0
   EndIf
Next Counter
glEnd
glDisable GL_TEXTURE_2D

EndIf


Danke!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 04.08.2010, 14:30    Titel: Antworten mit Zitat

Du musst mit dem Befehl zu jedem Punkt (den du mit glVertex bestimmst) angeben, welcher Punkt auf der Textur dazu gehört. Wie das funktioniert, kannst du z.B. in Stormys Tutorial erfahren.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
darkinsanity
aka sts


Anmeldungsdatum: 01.11.2006
Beiträge: 456

BeitragVerfasst am: 04.08.2010, 18:21    Titel: Antworten mit Zitat

Auf die Antwort kann man selbst kommen, wenn man sich klar macht, das OpenGL eine State-machine ist. Ein Status/Wert bleibt solange gesetzt, bis man einen neuen setzt.
Wenn du also eine Texturkoordinate setzt, gilt diese für alle nachfolgenden Koordinaten.
Du solltest also die Texturkoordinate am besten immer direkt vor der Koordinate setzten, d.h.:
Code:
glTexCoord2f (0,0)
glVertex3f (0,0,0)


Du solltest allerdings beachten, dass das Zeichnen per immediate-mode (mit glVertex3f usw.) veraltet und langsam ist.
Wenn du das ganze schnell machen willst, solltest du VBOs verwenden, in die du nur Dreiecke reinlegst. Andere Objekte werden nämlich dann erst in Dreiecke zerlegt.
Nur so als Zusatzinfo zwinkern
_________________
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
schildron



Anmeldungsdatum: 25.08.2008
Beiträge: 86

BeitragVerfasst am: 04.08.2010, 19:05    Titel: Antworten mit Zitat

So weit habe ich es jetzt auch geschafft. Ich rechne mir das Verhältnis mein Koordinatensystem - Texturkoordinatensystem aus.
Code:

'Texturkoordinatenstartpunkt Berechnen
'dicke/2 = Radius der Rundung am Ende der Linie
Dim As Single TexCoordStart, Plattformlange = Sqr((Punkt2X-Punkt1X)^2+(Punkt2Y-Punkt1Y)^2)+dicke   
TexCoordStart = (dicke/2)*(1/Plattformlange)

Die Textur wird auch geladen, allerdings ist das Ergebnis sehr verzerrt.

Code:
            If Counter < 10 Then
                glTexCoord2d TexCoordStart+X*(1/Plattformlange),0.5+Y*(1/Plattformlange)
                glVertex3f  Punkt1X + X, Punkt1Y + Y, -6.0
            ElseIf Counter = 10 Then
                glTexCoord2d TexCoordStart+X*(1/Plattformlange),0.5+Y*(1/Plattformlange)
                glVertex3f  Punkt1X + X, Punkt1Y + Y, -6.0
                glTexCoord2d 1-TexCoordStart+X*(1/Plattformlange),0.5+Y*(1/Plattformlange)
                glVertex3f  Punkt2X + X, Punkt2Y + Y, -6.0
            ElseIf Counter > 10 Then
                glTexCoord2d 1-TexCoordStart+X*(1/Plattformlange),0.5+Y*(1/Plattformlange)
                glVertex3f  Punkt2X + X, Punkt2Y + Y, -6.0
            EndIf


Ich rechne die Texturkoordinaten aus und lege Sie auf einen Punkt. Ich habe das bereits mit einer 100*400 Pixel und einer 400*400 Pixel Textur ausprobiert.
Leider sind sie sehr Verzerrt, vorallem wenn die Steigung der Linie größer ist.

Hinweis: Auf meiner Textur sind Rechtecke, und die werden als Kurven dargestellt.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
micha



Anmeldungsdatum: 09.12.2005
Beiträge: 72

BeitragVerfasst am: 05.08.2010, 02:52    Titel: Antworten mit Zitat

darkinsanity@

VBO's sind nur nützlich wenn Du die Vertexe nachträglich und häufig dynamisch ändern möchtest.
Feste, starre Geometrien wie z.B. ein Haus kann man besser mit Vertex3f ... Befehlen als OpenGL Liste kompelieren.

Daher sind diese Befehle keines weg's als "veraltet" zu bezeichnen.

Die tatsächle Umsetzung unterliegt sowieso der jeweiligen Renderpipeline.

Moderne Karten bzw. dessen Treiber benutzen "intern" meistens Trianglefans
weil sie mit weniger Speicher die gleiche Anzahl von Dreiecken beschreiben können.

Wen die Beschreibung einer Scene weniger Speicher benötigt
dann müssen auch weniger Daten durch die Pipelines "geschoben" werden
was mit einem, wenn auch geringem, Geschwindigkeitsgewinn belohnt wird.

Allein aus Gründen der Kompatibiltät muss man erst einmal abfragen ob überhaupt VBO's vorhanden sind.
Dies ist aber noch immer kein Garant dafür das diese
für "starre" Körper scneller sind als traditionelle kompelierte Displaylisten.

Z.B. Kommerzielle Engines rendern für den User unsichtbar
eine Scene mit starren Objekten mit und ohne VBO's
die Strategie mit der höheren Framerate bekommt dann den Zuschlag.

Als "Hobby" Programmierer kommt man sowie mit dem Tempo der OpenGL "Dekarden" nicht mehr mit.

Viele werkeln mit OpenGL 3.x herum und haben OpenGL 2.1 nur Ansatzweise ausgereitzt.
Ich selbst bin zu OpenGL 3.x noch nicht vorgestossen da ich erst einmal
mit OpenCL und CUDA den Pixeln das "Rennen" beigebracht habe.

Ist auf jeden Fall für den Interessierten ein spannendes Hobby.

Micha
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
darkinsanity
aka sts


Anmeldungsdatum: 01.11.2006
Beiträge: 456

BeitragVerfasst am: 05.08.2010, 18:31    Titel: Antworten mit Zitat

@micha:
Nein, VBOs sind auch für statische Geometrie geeignet. Außerdem IST der immediate mode veraltet - oder wie erklärst du es dir, das dir Khronos Group ihn mitsamt Displaylisten schon längst aus den neuen Standards rausgeschmissen hat?
Der Geschwindigkeitsunterschied zwischen Displayliste und VBO ist minimal. aber VBOs sind viel flexibler.
Außerdem sind VBOs schon längst Core, wenn du also nicht auf 20 Jahre alter Hardware OpenGL nutzt musst du keine Kompatibilität prüfen.

Wie kommst du darauf, dass die Treiber Trianglefans nutzen? Das Überprüfen, ob du ein Objekt in Trianglefans zerlegen kannst, wäre viel zu viel Overhead.
Der Overhead wäre auch durch den Geschwindigkeitszuwachs nicht auszugleichen.
Außerdem können Rasterizer nur normale Dreiecke verarbeiten.
Bei VBOs gibt es die Möglichkeit, einen Index-Buffer zu verwenden. Damit kann man Vertices einsparen und hat trotzdem keinen Overhead durch die Benutzung von Trianglefans oder Quads.
Schlussendlich sind VBOs bei ordnungsgemäßer Benutzung inzwischen schneller.

Und hast du mal daran gedacht, dass es einfach nicht sinnvoll ist, veraltete Dinge auszureizen? Zumal OpenGL 3+ wichtige Features wie den Geometry Shader eingeführt hat.

Btw heißt es nicht "Vertexe" sondern "Vertices" und auch nicht "kompelieren" sondern "kompilieren".

Ich beschäftige mich schon seit Jahren mit OpenGL - und glaub mir, VBOs sind die beste Möglichkeit, Geometrie zu rendern. Und bei OpenGL 3+ sind sie sogar die einzige Möglichkeit.
Meine Engine benutzt für die gesamte Geometrie - ob statisch oder dynamisch - nur VBOs.

@schildron:
Es ist auf jeden Fall sinnvoller, glTexCoord2f zu verwenden.
_________________
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
schildron



Anmeldungsdatum: 25.08.2008
Beiträge: 86

BeitragVerfasst am: 07.12.2010, 21:56    Titel: Antworten mit Zitat

Das oben beschriebene Problem habe ich gelöst, allerdings habe ich noch eine Frage.

Mein Beispielcode:
http://www.freebasic-portal.de/porticula/opengltexturen-1180.html
Die Textur "Textur.PNG" ist z.B. ein großes "A".

Ich hoffe Ihr könnt mir bei meinem Problem lösen:
Ich möchte ein gedrehtes Objekt mit einer gedrehten Textur darstellen.

Meinen Überlegungen nach sehe ich 2 Möglichkeiten:

Möglichkeit 1:
Die Textur drehen und dann auf das Objekt zu geben.
Leider habe ich keinen Ansatz wie man eine Textur dreht bevor man sie auf das Polygon gibt.

Möglichkeit 2: Das Polygon/Objekt "gerade" lassen, dann die Textur hinauf geben und dann das Objekt drehen.

Der Drehbefehl glRotatef 0.01, 0, 0, 1 dreht mir alle Objekt auf dem Bildschirm. Ein zurücksetzen nach dem drehen eines Objektes mit glRotatef -0.01, 0, 0, 1 geht auch nicht, weil sich sonst gar nichts mehr dreht.

Mein Code (Ergänzung zum oberen Beispiel):


Code:

Sub Objekt1 ()
   ''Viereck mit Textur erstellen
   glEnable GL_TEXTURE_2D
   glBindTexture GL_TEXTURE_2D, Textur_A
   
   glRotatef 0.02, 0, 0, 1

   glBegin GL_QUADS
   glColor3f 1.0,1.0,0.0
   glTexCoord2d 0,2 : glVertex3f  -2,  2, -6.0
   glTexCoord2d 2,2 : glVertex3f  -0.1,  2, -6.0
   glTexCoord2d 2,0 : glVertex3f  -0.1, 0.2, -6.0
   glTexCoord2d 0,0 : glVertex3f  -2, 0.2, -6.0
   glEND

   glRotatef -0.02, 0, 0, 1
   
   glBegin GL_QUADS
   glColor3f 1.0,1.0,0.0
   glTexCoord2d 0,2 : glVertex3f  0.1, -0.2, -6.0
   glTexCoord2d 2,2 : glVertex3f  2, -0.2, -6.0
   glTexCoord2d 2,0 : glVertex3f  2, -2, -6.0
   glTexCoord2d 0,0 : glVertex3f  0.1, -2, -6.0
   glEND
   
   glDisable GL_TEXTURE_2D
End Sub


Ich möchte erreich das sich ein Viereck dreht und eines still steht.

Danke im Voraus!
Schildron
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 07.12.2010, 22:13    Titel: Antworten mit Zitat

Hättest du OpenGL und Texturzuweisung verstanden, wäre es leicht.
Code:

   glTexCoord2d 0,2 : glVertex3f  -2,  2, -6.0
   glTexCoord2d 2,2 : glVertex3f  -0.1,  2, -6.0
   glTexCoord2d 2,0 : glVertex3f  -0.1, 0.2, -6.0
   glTexCoord2d 0,0 : glVertex3f  -2, 0.2, -6.0

Dieser Code weist jeweils einem Texel einer Textur einen Punkt auf deinem Quad zu. Mit Sinus-/Cosinus-Transformationen kannst du leicht errechnen, wie die eigentlichen texturkoordinaten aussehen müssen, wenn die textur rotiert sein soll. genau das tut auch glRotatef (da werden alle vektoren mit einer matrix, die mit sin/cos gefüllt ist, multipliziert).
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
darkinsanity
aka sts


Anmeldungsdatum: 01.11.2006
Beiträge: 456

BeitragVerfasst am: 08.12.2010, 22:23    Titel: Antworten mit Zitat

Falls du die Textur auf dem Objekt drehen willst, kannst du es dir leicht machen und die Texturmatrix benutzen: http://wiki.delphigl.com/index.php/Tutorial_Lektion_4#Texturen

Wenn du allerdings das Objekt an sich drehen willst, geht das auch einfach:
Code:

Sub Objekt1 ()
   ''Viereck mit Textur erstellen
   glEnable GL_TEXTURE_2D
   glBindTexture GL_TEXTURE_2D, Textur_A
   
   glLoadIdentity

   glBegin GL_QUADS
   glColor3f 1.0,1.0,0.0
   glTexCoord2d 0,2 : glVertex3f  -2,  2, -6.0
   glTexCoord2d 2,2 : glVertex3f  -0.1,  2, -6.0
   glTexCoord2d 2,0 : glVertex3f  -0.1, 0.2, -6.0
   glTexCoord2d 0,0 : glVertex3f  -2, 0.2, -6.0
   glEnd

   glRotatef -0.02, 0, 0, 1
   
   glBegin GL_QUADS
   glColor3f 1.0,1.0,0.0
   glTexCoord2d 0,2 : glVertex3f  0.1, -0.2, -6.0
   glTexCoord2d 2,2 : glVertex3f  2, -0.2, -6.0
   glTexCoord2d 2,0 : glVertex3f  2, -2, -6.0
   glTexCoord2d 0,0 : glVertex3f  0.1, -2, -6.0
   glEnd
   
   glDisable GL_TEXTURE_2D
End Sub


Damit wird das zweite Objekt gedreht, das erste jedoch nicht.
Noch eine kleine Notiz: Wenn es nicht wirklich notwendig ist, würde ich das An- und Abschalten der 2D-Texturen rausnehmen, denn unnötige Statechanges fressen unnötig Performance.

Ich kann dir nur raten, dich näher mit den DelphiGL-Tutorials zu befassen, da wird alles sehr gut erklärt.
_________________
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
schildron



Anmeldungsdatum: 25.08.2008
Beiträge: 86

BeitragVerfasst am: 09.12.2010, 18:42    Titel: Antworten mit Zitat

Danke für die bisherigen Antworten.

@darkinsanity
Danke das Du versucht hast Code zu liefern, allerdings habe ich deine Lösung schon früher ausprobiert, aber sie funktioniert (zumindest bei mir) nicht.
Wenn ich glLoadIdentity in den Code schreibe, dreht sich gar nichts mehr, wenn ich es weglasse drehen sich alle Vierecke.

Ich hoffe meine Fragen werden nicht als belastent und uninteressant angesehen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sebastian
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 5969
Wohnort: Deutschland

BeitragVerfasst am: 09.12.2010, 18:49    Titel: Antworten mit Zitat

schildron hat Folgendes geschrieben:
Ich hoffe meine Fragen werden nicht als belastent und uninteressant angesehen.

Nein, keine Sorge. zwinkern

@Jojo: Da sich das Forum an QB-/FB-Programmierer aller Erfahrungslevels und ausdrücklich auch an Einsteiger richtet, muss man auch mal vermeintlich einfache Fragestellungen "abkönnen". zwinkern
_________________

Der Markt regelt das! | Opas Leistung muss sich wieder lohnen - für 6 bis 10 Generationen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 09.12.2010, 19:03    Titel: Antworten mit Zitat

Sebastian hat Folgendes geschrieben:
@Jojo: Da sich das Forum an QB-/FB-Programmierer aller Erfahrungslevels und ausdrücklich auch an Einsteiger richtet, muss man auch mal vermeintlich einfache Fragestellungen "abkönnen". zwinkern

Schau mal, wann der Thread begonnen wurde. Der Threadstarter programmiert also offensichtlich schon seit mehreren Monaten mit OpenGL. Da könnte man schon draufgekommen sein, was der konsektutive Aufruf von glTexCoord2d und glVertex3f eigentlich macht...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
darkinsanity
aka sts


Anmeldungsdatum: 01.11.2006
Beiträge: 456

BeitragVerfasst am: 09.12.2010, 19:09    Titel: Antworten mit Zitat

Ah, Moment, ich glaube jetzt hab ich verstanden was du meinst. Wenn du glRotatef immer wieder aufrufst, ohne die Matrix per glLoadIdentity zurückzusetzen, wird immer weitergedreht.
Wenn du jedoch zwischendurch glLoadIdentity aufrufst, wird die Matrix zurückgesetzt, wenn du danach wieder rotierst wird das was du zeichnest, zwar rotiert, aber in jedem Frame wird halt eben erst zurückgesetzt und dann rotiert, wodurch du keine "Animation" sehen kannst.

Meine Lösung funktioniert wie du es erwartest, wenn du die -0.02 bei glRotatef durch eine Variable ersetzt, die du pro Durchlauf erhöhst bzw. verringerst.


Alternativ liese sich das noch über den Matrix-Stack lösen, aber das würde dich vermutlich nur verwirren happy
_________________
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Bibliotheken Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz