1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. minx

Beiträge von minx

  • OpenGl Tutorial

    • minx
    • 11. November 2012 um 17:44

    [Blockierte Grafik: http://s14.directupload.net/images/121217/6gcjtxek.png]

    Palim, palim!

    Jetzt möchte ich auch mal mein erstes "richtiges" Tutorial schreiben. Es geht sich hierbei im OpenGl.

    1. Was ist OpenGl?

    OpenGL (Open Graphics Library) ist eine Spezifikation für eine plattform- und
    programmiersprachenunabhängige Programmierschnittstelle zur Entwicklung von 2D- und 3D-Computergrafik.
    Der OpenGL-Standard beschreibt etwa 250 Befehle, die die Darstellung komplexer 3D-Szenen in Echtzeit erlauben.
    Zudem können andere Organisationen (zumeist Hersteller von Grafikkarten) proprietäre Erweiterungen definieren.

    1.1 In welcher Form liegt OpenGl uns bereit?

    Da wir mit AutoIt und Windows programmieren, so ist nur die von Microsoft vorgestellte Ordnung relevant. Unter
    Windows steht und OpenGl in Form einer DLL Bibliothek zur Verfügung. Zur Angenehmeren Bearbeitung mit
    AutoIt benutzen wir aber eine UDF.

    1.2 EINE UDF...

    Unbestimmter Artikel. Es gibt eben nicht nur DIESE UDF, mit der wir uns zufrieden geben können. Anfangs bestand
    die Unterstützung von OpenGl für AutoIt aus einer bloßen Liste von DLL Calls. Dann haben mehr als ein Dutzend
    User die verschiedensten Dinge zusammengezimmert. Einige mit anderen UDFs, anderen DLLs, als Plugin usw.
    Das Problem ist: Bei allen funktioniert irgendwas nicht richtig.

    Aus diesem Grund habe ich mich mal durch die Berge an Code gewühlt, VORBEI an gfwl, soil, glut und Konsorten, um
    einfach erst einmal den Umgang zu erleichtern, und mich ganz auf OpenGL beschränkt. Entstanden ist eine grooooße
    Datei mit nahezu allen Funktionen der opengl32.dll und ebenso, nahezu allen Konstanten.

    Mit DIESER UDF ist nun ein nahezu natloses Übersetzen von OGl Quelltext aus anderen Sprachen nach AutoIt
    möglich, man muss dabei nicht groß umdenken, und kann so fast jedes OGl Tutorial benutzen. (Aber jetzt erstmal
    hiergeblieben! ;) )

    2. Die Befehle

    Die Befehle für OpenGl sind in jeder Sprache gleich und beginnen mit "gl". Untersuchen wir mal einen kleinen
    Befehl: "glVertex3f". Dieser Befehl gibt uns in 4 Dingen Auskunft:

    1. gl -> opengl32.dll
    2. Vertext -> Es geht um die Erstellung eines Vertex, also einen Punkt im Raum. Dies ist der Funktionsname
    3. 3 -> Zahl der Parameter
    4. f -> Die Zahlen sind floats

    Wenden wir das an. Wir wollen also einen Punkt mit den Koordinaten, sagen wir, (0|0|0) zeichnen, also genau
    mittig. Dann wäre der Syntax in AutoIt: "glVertex3f(0,0,0)".

    Eigentlich sehr einfach. Die floats dürfen im Übrigen von 0.00 bis 1.00 gehen.

    3. Konzept der statischen Werte

    Wenn im Skript einmal etwas festgelegt wird, zum Beispiel mit "glColor3f(1,0,0)", die Farbe auf Rot, so ver-
    bleibt diese Einstellung bis man erneut diesen Befel mit anderen Paramtern aufruft.

    4. Primitiven

    OpenGl arbeitet mit Primitiven, wird deshalb auch Low Level 3D Engine genannt. WIr können damit also Punkte, Linien,
    Dreiecke, Quadrate und Polygone zeichnen. (Ja, richtig, keine Kreise oder 3D Objekte).

    5. Vertexe

    Alle Primitven müssen von uns aus Vertexen aufgebaut werden. Wir haben mehrere Befehle um solche Vertexe im
    Raum zu generieren, aber der Wichtigste für uns ist: "glVertex3f(xf,yf,zf)".

    Wir brauche immer die Ecken der Primitven, das heißt also wir benötigen für einen Punkt einen Vertex, für eine
    Linie 2, für ein Dreieck 3 und so weiter. Geben wir 4 Vertexe hintereinander an, und haben den "Linienstyle"
    drin, so werden zwei Linien, eine vom 1. bis zum 2. und eine vom 3. bis zum 4. Punkt erstellt. Also nimmt
    uns hier OGl etwas Arbeit ab.

    6. Farben

    Farben sind so eine Sache in OepnGl. Wir haben hier hauptsächlich zwei Möglichkeiten die Farbe für die nach-
    folgenden Befehle zu setzen. Zum Beispiel im 3f Raum:

    - glColor3f(rf,gf,bf) -> Die Zahlen werden hier als floats angegeben
    - glColor3ub(r,g,b) -> Zie Zahlen werden jetzt von 0 bis 255 angegeben

    Wenn alle Vertexe die gleiche Farbe haben, hat das Primitiv als Ganzes auch diese Farbe. Beispiel: 4 Rote
    Vertexe im Quadstyle erzeugen ein rotes Quadrat.

    Wenn die Farben unterschiedlich sind, müssen wir festlegen was passieren soll. Dies tun wir mit
    "glShadeModel($Style)"

    - $GL_FLAT -> Für Linien/Dreiecke die Farbe des letzten Vertex, für Quads die des Ersten
    - $GL_SMOOTH -> Interpolierter Farbverlauf zwischen allen Vertexen

    7. Koordinaten

    Die Koordinaten im Zeichenfeld sind etwas anders als in einer normalen GUI. x0, y0 beschreiben jetzt den Mittel-
    punkt des Fensters und die Z-Achse "ragt" aus dem Bildschirm dem Betrachter entgegen. Positive Rotationen
    um Achsen erfolgen stets entgegengesetzt dem Uhrzeigersinn.

    8. Der Viewport

    Der Viewport ist ein rechteckiger Ausschnitt der Gesamtzeichenfläche, die am Ende definiert, was der Benutzer
    sieht. Also sozusagen das "Fenster" zur gezeichneten Welt. Normalerweise, wenn man nichts festlegt, so nimmt der
    Viewport die ganze Zeichenfläche ein. Das ganze wird angegeben wie bei einem Control, obwohl hier der Start-
    punkt unten Links ist. Also x0, y0 vom Viewport ist die linke untere Ecke. Der Befehl ist hier:
    "glViewport(x,y,w,h)"

    9. Transformationen

    OpenGl bietet viele Möglichkeiten eine 3D Szene zu verändern. Dies nennt man Transformation. Transformation reicht
    von dem totalen Verändern einer Szene bis hin zum einfachen setzen des Viewpunkts. Die Transformations-
    befehle werden in 3 Typen eingeteilt:

    9.1 Projektion

    Diese Befehle brauchen wir, um eine 3D Szene auf unseren 2D Bildschirm abzubilden. Dabei wird perspektivische
    und orthographische Abbildung unterstützt. Bei einer orthographischen Darstellung entfällt der Schrumpf-
    effekt bei weiter hinten liegenden Obejkten im Raum (-> die Perspektive).

    9.2 Viewing

    Wir gehen bei OpenGl "Kameras" immer von Beobachtern aus, die immer einen Standpunkt und einen punkt haben, auf
    den sie schauen. (Ähnlich wie bei DirectX mit dem Eye Vector). Die Viewing Befehle manipulieren diese Punkte.

    9.3 Modeling

    Wohl der wichtigste Transformationstyp. Mit diesen Befehlen können wir Objekte in der Szene bewegen (move),
    rotieren (rotate) und deren Größe ändern (scale).

    Bevor wir uns nun noch einmal genauer mit der etwas komplexen Transformation befassen, hier mal kurz die Befehle:

    Transformationen
    [autoit]

    ; Projection
    glFrustum($fLeft, $fRight, $fBottom, $fTop, $fNearVal, $fFarVal)
    glOrtho($fLeft, $fRight, $fBottom, $fTop, $fNearVal, $fFarVal)

    [/autoit] [autoit][/autoit] [autoit]

    ; Viewing
    glViewport($iX, $iY, $iWidth, $iHeight)

    ; Modeling
    glTranslatef($fX, $fY, $fZ)
    glRotatef($fAngle, $fX, $fY, $fZ)
    glScalef($fX, $fY, $fZ)

    [/autoit]

    -> 9.1 Über das Transformieren der Projektion.

    OpenGl arbeitet mit dem Prinzip eines 3D Sichtfeldes, das durch einen Körper definiert wird (View Volume).
    Alles in diesem Volume wird angezeigt, alles andere nicht. WIr unterscheiden zwischen Orthographisch
    (Parallele Projektion) und die Perspektivische Projektion.

    Parallele Projektion (Bild1)

    [Blockierte Grafik: http://www.csee.umbc.edu/~rheingan/435/…iew/view2-3.gif]

    Perspektivische Projektion (Bild2)

    [Blockierte Grafik: http://www.csee.umbc.edu/~rheingan/435/…iew/view2-5.gif]

    In der Parallelen Projektion ist das Volume einfach eine Box, ein Quader im Raum, das bedeutet praktisch, das
    die Distanz der Objekte in diesem Volume zum Beobachter keinen Größenunterschied aufweisen. Der Flucht-
    effekt entfällt. Benutzt wird diese, auf den ersten Blick sinnlose, Darstellung für architektonische Pläne
    und Blaupausen, bei denen die Proportionen der projezierten Objekte erkennbar sein muss.

    Bei der Perspektivischen Projektion ist das Volume ein Stumpf (zu englisch: frustum), also haben wir hier
    eindeutig einen Fluchteffekt, der die ganze Szene real und tief erscheinen lässt. Einfach wie unsere Augen
    funktionieren. Auf diesen Modus beschränken wir uns. Die Sichtweite ist aber wichtig. Ein (Pyramiden)stumpf ist
    ein Ausschnitt aus der Grundfigur (Pyramide), der zwischen zwei parallelen Deckflächen definiert ist.
    Die dem Beobachter zugewandte Deckfläche heißt "Near Plane" und die dahinter "Far Plane". Man kann nun die Sicht-
    weite definieren, in dem man festlegt, wie weit hinten die Far Plane liegen soll. Liegt sie zum Beispiel
    unendlich weit hinten, so werden alle Objekte, die perspektivisch vor dieser Plane liegen, dargestellt.

    Skizze des Fluchtsystems - Fluchtpunkt A in der Mitte (Bild3)

    [Blockierte Grafik: http://www.klassentagebuch.de/4456.jpg]

    Wir erinnern uns an die Befehle:
    - glOrthographic - Paralleles Volume
    - glFrustum - Damit erstellen wir einen unregelmäßigen Stumpf

    Default ist die Perspektivische Projektion gesetzt, und das lassen wir mal so, wir werden also hier nichts mehr
    ändern.

    -> 9.3 Über das Transformieren der Models

    9.3.1 glTranslatef

    Wer schon einmal mit uralten 3D CAD Systemen gearbeitet hat, wird noch wissen, dass eine Bewegung eines Objektes
    fast immer die Differenz fordert, das heißt um wie viel "Weg" soll das Objekt bewegt werden. Zum Beispiel:
    "glTranslatef(.05,0,0)" verschiebt das Objekt um .05 in X-Richtung.

    9.3.2 glRotatef

    Dieser Befehl rotiert das Objekt. Dabei wird erst der Winkel angegeben, und dann ein boolscher Wert für die Achsen.
    Wenn das Objekt jetzt also zum Beispiel um 30° um die X-Achse rotiert werden soll, so lautet der Syntax:
    "glRotatef(30, 1, 0 , 0".

    10. Matrizen

    Jetzt können sich die freuen, die keine Matrixrechnung beherrschen! Denn OpenGl verwendet zwar laufend Matrizen,
    aber nimmt uns die Rechnung damit völlig ab.

    OpenGl nutzt für die Speicherung des Status einer Szene drei Matrizen: ModelView, Projection und Texture.
    Es kann zu einem Zeitpunkt immer nur EINE Matrix angewählt sein, um darin Änderungen vorzunehmen. Wir sehen
    uns mal kurz die Modi an:

    - ModelView - Primitiven zeichnen und verändern
    - Projection - Perspektive verändern
    - Texture - Material für Primitiven festlegen

    Wie verfahren wir mit Matrizen? Schritt für Schritt:

    1. Auswählen der Matrix
    2. Matrix leeren
    3. Verändern von irgendwas
    4. Anzeigen

    Für Codeabfolge, und das ist jetzt sehr wichig, müssen wir folgend verfahren:

    1. Matrix auswählen
    2. Matrix leeren
    3. Zeichenfeld leeren
    4. Paramter setzen (Rotation, ...)
    5. Primitiven zeichnen
    6. Anzeigen

    10.1 Matrix Stack

    Ein Stack ist ein Stapelspeicher. Man muss ihn sich vorstellen wie ein Stapel Papier, auf dem Eigenschaften ge-
    speichert sind und wieder geladen werden können. Dieses Speichern und Lesen bei Stacks nennt man Push und Pop.
    Die Befehle dazu sind:

    - glPushMatrix
    - glPopMatrix

    Mit diesen Befehlen kommunizieren wir mit dem automatisch angelegten Stack.
    Lest euch bitte erstmal diesen Code durch, ich weiß, dass wir noch nicht alle Befehle besprochen haben, aber
    es geht um die Struktur und den Aufruf der Stack Kommandos:

    Matrix Stack (Code1)
    [autoit]


    Func DrawScene()
    glClear($GL_COLOR_BUFFER_BIT) ; Buffer leeren
    glLoadIdentity() ; ModelView leeren

    [/autoit] [autoit][/autoit] [autoit]

    glPushMatrix() ;Speichert alle Einstellung der aktuellen Matrix

    [/autoit] [autoit][/autoit] [autoit]

    glRotatef(25,1,1,1) ; Rotieren

    glBegin($GL_POINTS)
    glVertex3f(0,0,0) ;Rotierten Punkt erstellen
    glEnd()

    glPopMatrix() ;Alte Einstellungen laden (Keine Rotation...)

    glRotatef(40,1,1,1)

    glBegin($GL_POINTS)
    glVertex3f(1,1,0) ;Rotierten (40°) Punkt erstellen
    glEnd()

    [/autoit] [autoit][/autoit] [autoit]

    SwapBuffers($hDC) ;Anzeigen
    EndFunc

    [/autoit]

    Würden wir nicht mit dem Stack arbeiten, wäre der zweite Vertex 2x(!) rotiert worden! Beachtet das! Schafft euch
    am Besten immer einen Ausgangszustand, auf den ihr dann im Stack zurückgreifen könnt, das erleichtert das
    Arbeiten.

    Man, war das ein langer Punkt ...

    11. Optimierung

    Wir haben gleich 3 Optionen um das Aussehen unserer Szene zu verbessern, was natürlich erst für größere Welten
    relevant ist. Alle Optionen sind sinnvollerweise by default ausgeschaltet, um die Performance zu verbesser.
    Folgende Optionen können wir nutzen:

    - Doublebuffer - Das Prinzip ist klar. Alles wird auf eine 2., unsichtbare Fläche gezeichnet und dann angezeigt
    - HSR (Hidden Surface Removal) - verbessert die Performance, indem nicht beobachtbare Flächen nicht gezeichnet
    werden
    - Culling - Wie bei DirectX ist hiermit das selektive Zeichnen gemeint. Das heißt nach hinten gerichtete Flächen
    werden z.B. nicht gezeichnet

    11.1 Double Buffer

    Der Double Buffer, für alle die noch nie etwas davon gehört haben, erzeugt ein Back Interface, also eine für
    den User unsichtbare Zeichenfläche, auf die gezeichnet wird, während die erste noch angezeigt ist. Ist das
    Hintergrundzeichnen fertig werden die Buffer geswapt, also getauscht und alles geht von vorn los. Das ist etwas
    Ressourcenlastig, aber nötig für eine flüssige Animation und in meiner UDF immer aktiviert.

    Double Buffer wird von der Windows API verwaltet und bezieht sich somit auf den Fensterkontext, nicht auf den
    Renderkontext. In der Hauptschleife wird einfach ein "glSwapBuffers" angehängt. Dies wird aus der GDI32.dll be-
    zogen und ist somit keine Standard OpenGl32.dll Funktion! GDI muss vorhanden sein!

    11.2 HSR

    Obwohl wir eine 2D Zeichenfläche haben, können wir einen Z-Buffer, also einen Tiefenbuffer für jeden Pixel hin-
    zufügen. Was? Ganz einfach: bevor ein Pixel eines Objektes gezeichnet wird, wird ein Vergleich mit dem
    Tiefenbufferwert des Pixels angestellt. Wenn der neue Pixel näher am Near Panel liegt, also vor diesem Wert,
    wird der Buffer mit den neuen Daten überschrieben und der Pixel wird gezeichnet. Wenn der Pixel verdeckt ist,
    also der Bufferwert hinter einem anderen Pixel liegt, so wird er nicht gezeichnet, aber der Buffer bleibt
    erhalten.

    HSR (Code2)
    [autoit]

    glEnable($GL_DEPTH_TEST) ; Depth Buffer an
    glClear($GL_DEPTH_BUFFER_BIT) ; Depth Buffer leeren

    [/autoit]

    11.3 Culling

    Eine Fläche hat zwei Seiten. Ein Primitv, zum Beispiel ein Quadrat hat eine Vorder- und eine Rückseite. Die
    Rückseite müssen wir ja eigentlich nicht zeichnen. Diese Flächen von der Zeichenroutine auszuschließen heißt
    Culling.

    Culling (Code3)
    [autoit]

    glEnable($GL_CULL_FACE) ; Culling für Flächen an
    glCullFace($GL_BACK) ; Rückseite cullen (/$GL_FRONT)

    [/autoit]

    12. Beispiele

    Fck yeah! Wir haben den ganzen Theoriemist erledigt, jetzt geht es ans Eingemachte. Klar, das wir nicht auch
    noch die ganze 3D Mathe-Theorie machen wollen (zumindes ich nicht). Dafür gibt es andere Hilfen und das eigene
    Gehirn ;)

    Übrigens: Das Zeichenfeld hat die Maße -1 bis 1. Also ein Koordinatensystem mit den Maßen 1 in jede Richtung. Deshalb verwenden wir Werte von 0.00 bis 1.00!

    12.1 Erste Gehversuche

    Um jetzt irgendwas zu machen, beginnen wir erstmal mit dem Include.

    [autoit]

    #include <gl.au3>

    [/autoit]

    Danach brauchen wir einen Container für die Zeichenfläche. Das ist eine ganz normale GUI, es kann sogar eine
    Child GUI sein. Diese benutzen wir im Eventmodus. Desweiteren brauchen wir noch zwei freie Variabeln:
    $dc und $rc für Handles. Also:

    [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit][autoit][/autoit][autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit]

    Nun müssen wir OpenGL hochfahren und die Zeichenfläche auf die GUI legen. Gleichzeitig überprüfen wir noch
    auf Fehler:

    [autoit]

    If Not glInit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit]

    Wir setzen nun den Matrix Modus. Da wir zeichnen wollen, also eine Projection erstellen wollen gehen wir in
    diesen Modus mit:

    [autoit]

    glMatrixMode($GL_PROJECTION)

    [/autoit]

    Jetzt zeigen wir noch die GUI an. Dann haben wir Platz zum Zeichnen!

    [autoit]

    GUISetState()

    [/autoit]

    In unsere Schleife kommt jetzt die Zeichnung. Wir wollen jetzt 2 Linien zeichen. Wir leeren erst den Buffer,
    stellen auf Linien um, setzten eine Farbe und geben dann 4 Punkte an. OpenGl erkennt automatisch, dass es 4
    Punkte sind, aber nur 2 pro Linie gebraucht werden. So wir eine Linie vom 1. zum 2. und vom 3. zum 4. ge-
    zeichnet. Dann beenden wir die Zeichnung und swappen die Buffer!

    Schleife mit Zeichnung (Code4)
    [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    glClear($GL_COLOR_BUFFER_BIT)
    glBegin($GL_LINES)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3ub(0, 255, 0)

    [/autoit] [autoit][/autoit] [autoit]

    glVertex3f(0, .5, 0)
    glVertex3f(0, -.5, 0)

    [/autoit] [autoit][/autoit] [autoit]

    glVertex3f( -.5, 0, 0)
    glVertex3f( .5, 0, 0)
    glEnd()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    glSwapBuffers($dc)

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit]

    Nun brauchen wir noch die definierte Quit-Funktion. Dabei müssen alle Handles wieder freigegeben werden und das
    Programm beendet. Das erste übernimmt alles die UDF. Die Funktion wird genauso aufgerufen wie glInit():

    [autoit]

    Func quit()
    glTerminate($gui, $dc, $rc)
    Exit
    EndFunc

    [/autoit]

    Also ist unser komplettes Beispiel:

    Fadenkreuz komplett (Code5)
    [autoit]

    #include <gl.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit] [autoit][/autoit] [autoit]

    If Not glInit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    glMatrixMode($GL_PROJECTION)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    glClear($GL_COLOR_BUFFER_BIT)
    glBegin($GL_LINES)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3ub(0, 255, 0)

    [/autoit] [autoit][/autoit] [autoit]

    glVertex3f(0, .5, 0)
    glVertex3f(0, -.5, 0)

    [/autoit] [autoit][/autoit] [autoit]

    glVertex3f( -.5, 0, 0)
    glVertex3f( .5, 0, 0)
    glEnd()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    glSwapBuffers($dc)

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func quit()
    glTerminate($gui, $dc, $rc)
    Exit
    EndFunc

    [/autoit]

    12.2 Farbverlauf und Viereck

    Ein Quadrat unter OpenGl ist eigenlich nur ein Viereck, das heißt, es muss nicht regelmäßig sein.

    Wir starten wieder Opengl:

    Init (Code6)
    [autoit]

    #include <gl.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit] [autoit][/autoit] [autoit]

    If Not glinit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    glMatrixMode($GL_PROJECTION)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit]

    Dann müssen wir die Zeichnung mit $GL_QUADS beginnen und 4 Punkte festlegen. Für jeden Punkt legen wir vorher
    noch eine andere Farbe fest. Wir wollen mal alle Farben, also RGB verwenden und noch eine. Gelb nehmen wir mal.
    Gelb ist ja bekanntlich RG. Dann fügen wir noch die Quit-Funktion an, und fertig!

    Beispiel Farbverlauf komplett (Code7)
    [autoit]

    #include <gl.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit] [autoit][/autoit] [autoit]

    If Not glinit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    glMatrixMode($GL_PROJECTION)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    glClear($GL_COLOR_BUFFER_BIT)

    [/autoit] [autoit][/autoit] [autoit]

    glBegin($GL_QUADS)

    [/autoit] [autoit][/autoit] [autoit]

    glColor4f(1, 0, 0, 0)
    glVertex4f(0, .5, 0, 1)
    glColor4f(0, 1, 0, 0)
    glVertex4f( -.5, 0, 0, 1)
    glColor4f(1, 1, 0, 0)
    glVertex4f(0, -.5, 0, 1)
    glColor4f(0, 0, 1, 0)
    glVertex4f( .5, 0, 0, 1)

    [/autoit] [autoit][/autoit] [autoit]

    glEnd()

    [/autoit] [autoit][/autoit] [autoit]

    glSwapBuffers($dc)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func quit()
    glTerminate($gui, $dc, $rc)
    Exit
    EndFunc

    [/autoit]

    12.3 Verrückte Dinge

    Wir können unter OpenGl folgende Formen zeichnen:

    Primitven in OpenGl (Bild4)

    [Blockierte Grafik: http://www.naturewizard.com/Tutorials/Tuto…es/image009.jpg]

    Wir sehen, da sind zum Beispiel kombinierte Formen dabei. Die sollte man immer anstatt der einzelnen verwenden,
    sie werden nämlich schneller gerendert.

    Aber wir haben ein Problem! Es gibt keine Kreise. Überlegen wir mal, aus was wir einen Kreis aufbauen können.
    Entscheiden wir uns mal der Freundlichkeit zur Grafikkarte halber für Dreiecke. Wir haben ein nützliches
    Primitiv: Den Triangle Fan. Ein Kreis ist nichts anderes als ein Triangle Fan mit so vielen Ecken, dass er
    rund aussieht. Dazu müssen Punkte, so viele wie wir wollen, alle mit gleichen Abstand in einer Kreisbahn
    erstellt werden. Diese Punkte nennt man nun Stacks, oder Sticks. Wir brauchen also eine Variable

    [autoit]

    Local $CircleStacks = 50

    [/autoit]

    Wir können theoretisch 360 Stacks im Kreis unterbringen, müssen wir aber nicht. 50 reichen locker. Wie man
    die Punkte berechnet sollte klar sein. Allerdings müssen wird die Winkel umrechnen, dazu brauchen wir die
    Funktion "_Radian" aus der Math.au3.

    Die Zeichenfunktion sieht also so aus:

    [autoit]

    For $i = 0 To 360 Step 360/$CircleStacks
    $x = .5 * Sin(_Radian($i))
    $y = .5 * Cos(_Radian($i))
    glVertex3f($x,$y,0)
    Next

    [/autoit]

    Nun wars das schon. Noch aufräumen und so weiter und fertig ist der Kreis. Je weniger Stacks der Kreis nun hat,
    desto unrunder (=zackiger) sieht er aus.

    Beispiel Kreis komplett (Code8 )
    [autoit]

    #include <gl.au3>
    #include <Math.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $CircleStacks = 50

    [/autoit] [autoit][/autoit] [autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit] [autoit][/autoit] [autoit]

    If Not glInit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    glMatrixMode($GL_PROJECTION)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    glClear($GL_COLOR_BUFFER_BIT)

    [/autoit] [autoit][/autoit] [autoit]

    glBegin($GL_TRIANGLE_FAN)
    glColor3f(1, 0, 0)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 360 Step 360/$CircleStacks
    $x = .5 * Sin(_Radian($i))
    $y = .5 * Cos(_Radian($i))
    glVertex3f($x,$y,0)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    glEnd()
    glSwapBuffers($dc)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func quit()
    glTerminate($gui, $dc, $rc)
    Exit
    EndFunc

    [/autoit]

    12.4 Die dritte Dimension

    ... war die ganze Zeit schon da ^^. Wir haben vorhin gelernt, wie wir ein Rechteck zeichnen. Um nun einen Würfel
    zu erstellen brauchen wir 6 Seiten, für die wir jeweils alle 4 Eckpunkte angeben müssen. Um den User
    nun komplett zu verwirren, wird jede Seite ein Farbverlauf und wir rotieren den Würfel am Ende noch.

    Dazu brauchen wir eine Variable, die die Rotation hält, und die wir jeden Durchlauf erhöhen. Dann rotieren wir
    mit den bekannten Befehlen und ... fertig! Unsere erste 3D Szene!

    3D Szene komplett (Code9)
    [autoit]

    #include <gl.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $rotation = 0

    [/autoit] [autoit][/autoit] [autoit]

    Global $gui = GUICreate("OpenGL", 250, 250), $dc, $rc
    GUISetOnEvent(-3, "quit")

    [/autoit] [autoit][/autoit] [autoit]

    If Not glinit($gui, $dc, $rc) Then
    MsgBox(48, "Error", "Error bei der Initialisierung von OpenGL-Funktionen" & @CRLF & "Error code: " & @error)
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    glMatrixMode($GL_PROJECTION)
    glEnable($GL_DEPTH_TEST)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    glClear($GL_COLOR_BUFFER_BIT + $GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

    [/autoit] [autoit][/autoit] [autoit]

    glRotatef(45, 1, 0, 1)
    glRotatef($rotation, 0, 1, 0)

    [/autoit] [autoit][/autoit] [autoit]

    glBegin($GL_QUADS)
    glColor3f(0, 0, 0)
    glVertex3f(-.5, -.5, -.5)
    glColor3f(0, 0, 1)
    glVertex3f(-.5, -.5, .5)
    glColor3f(0, 1, 1)
    glVertex3f(-.5, .5, .5)
    glColor3f(0, 1, 0)
    glVertex3f(-.5, .5, -.5)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3f(1, 0, 0)
    glVertex3f( .5, -.5, -.5)
    glColor3f(1, 0, 1)
    glVertex3f( .5, -.5, .5)
    glColor3f(1, 1, 1)
    glVertex3f( .5, .5, .5)
    glColor3f(1, 1, 0)
    glVertex3f( .5, .5, -.5)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3f(0, 0, 0)
    glVertex3f(-.5, -.5, -.5)
    glColor3f(0, 0, 1)
    glVertex3f(-.5, -.5, .5)
    glColor3f(1, 0, 1)
    glVertex3f( .5, -.5, .5)
    glColor3f(1, 0, 0)
    glVertex3f( .5, -.5, -.5)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3f(0, 1, 0)
    glVertex3f(-.5, .5, -.5)
    glColor3f(0, 1, 1)
    glVertex3f(-.5, .5, .5)
    glColor3f(1, 1, 1)
    glVertex3f( .5, .5, .5)
    glColor3f(1, 1, 0)
    glVertex3f( .5, .5, -.5)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3f(0, 0, 0)
    glVertex3f(-.5, -.5, -.5)
    glColor3f(0, 1, 0)
    glVertex3f(-.5, .5, -.5)
    glColor3f(1, 1, 0)
    glVertex3f( .5, .5, -.5)
    glColor3f(1, 0, 0)
    glVertex3f( .5, -.5, -.5)

    [/autoit] [autoit][/autoit] [autoit]

    glColor3f(0, 0, 1)
    glVertex3f(-.5, -.5, .5)
    glColor3f(0, 1, 1)
    glVertex3f(-.5, .5, .5)
    glColor3f(1, 1, 1)
    glVertex3f( .5, .5, .5)
    glColor3f(1, 0, 1)
    glVertex3f( .5, -.5, .5)
    glEnd()

    [/autoit] [autoit][/autoit] [autoit]

    $rotation = $rotation + 0.5

    [/autoit] [autoit][/autoit] [autoit]

    glSwapBuffers($dc)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func quit()
    glTerminate($gui, $dc, $rc)
    Exit
    EndFunc

    [/autoit]

    13. Fazit

    So das wars erstmal mit Beispielen. Jetzt dürfte alles klar sein und ihr könnt loslegen mit verrückten Sachen.
    Vielleicht wäre auch eine UDF angebrahct, für Kugel, Zylinder und so weiter, wenn jemand lange Weile hat :D

    14. FAQ

    F: Warum nicht das Plugin verwenden?
    A: Es ist langsam, inkompatibel mit Windows 7 und stürzt gern mal ab. Witer kann man damit auch keien Skripte
    aus anderer Sprache portieren.

    F: Warum OnEvent und nicht Msg?
    A: Mit OnEvent wird immer die miximale Framerate erzielt. Bei Msg läuft bei Inaktivität, zum Beispiel wenn
    sich die Maus nicht in der GUI bewegt, die Zeichnung auf Sparflamme

    F: Warum benutzt du ".5"?
    A: Ist eine ganz normale Schreibweise für 0.5 in Programmiersprachen.

    F: -Hier könnte deine Frage stehen-
    A: -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    15. Antworten in diesem Thread

    Bitte gliedert eure Antworten in diesem Thread in zwei Teile:

    1. Fragen / Anmerkungen zum Thema und auf das Tut bezogene Themen
    2. Formale Fehler und Anmerkungen für das Tut, wie Rechtschreibung usw.

    16. 3D Grafik Ring

    Irrlicht - OpenGL - DirectX - Tiny3D - au3impact

    mfG, minx :thumbup:

    Dateien

    Fadenkreuz.au3 672 Byte – 619 Downloads Farbverlauf.au3 774 Byte – 580 Downloads Kreis.au3 760 Byte – 573 Downloads Cube.au3 1,93 kB – 587 Downloads
  • AutoIt auf Win8?

    • minx
    • 11. November 2012 um 17:23

    Vor allem die WinAPI Sachen sind bei der Metrofläche nicht mehr anwendbar.

  • >Orion<

    • minx
    • 11. November 2012 um 00:07

    Wir werden dir schon hochhelfen :whistling:

  • >Orion<

    • minx
    • 9. November 2012 um 13:18

    Hallo, wir kenne uns ja schon ^^
    Dann nochmal ganz offiziell: Willkommen.

    PS: Schon wieder einer der tausend User mit diesem Zitat in der Sig :D :D

  • TCP nur Lokal oder Internetfähig?

    • minx
    • 9. November 2012 um 07:23

    Du musst im Router eine Portweiterleitung für deine IP und den Port erstellen. Dann musst brauchst du noch eine DNS Weiterleitung, da deine Router IP dynamisch ist. Die Daten, von z.B. DynDNS trägst du dann im Router ein, und fertig ;)

  • [gelöst] Mittelpunkt einer Fläche im 3D Raum

    • minx
    • 6. November 2012 um 17:29

    Danke für die Hilfe.

    Da ich diese Funktion später auch für nicht symmetrische Flächen verwenden möchte, habe ich nun eine Schittpunktberechnung mit 3-3 Gleichungssystem erstellt. Funktiuoniert soweit ganz gut :D

  • [gelöst] Mittelpunkt einer Fläche im 3D Raum

    • minx
    • 5. November 2012 um 19:51

    Tach.

    Folgendes Problem habe ich bei meinem Skript (geht um 3D Darstellung). Es sind 4 Eckpunkte gegeben (x;y;z) [Z ist hier der Abstand nach Oben/Unten = Höhe], die zusammen eine rechteckige Fläche im 3D Raum bilden. Nun möchte ich den Schnittpunkt der Diagonalen in diesem Rechteck, also den Mittelpunkt, haben, als 3D Koordinate, also wieder (x;y;z).

    Hat da jemand eine Idee. Ich finde keinen richtigen Ansatz.

    Danke!

  • Threads mit 3 Monaten Inaktivität sperren

    • minx
    • 4. November 2012 um 17:55

    Der letzte Post ist relevant. Der Startpost wurde schon lange vorher gelöscht, während das Projekt noch lief, was sich relativ leicht aus dem Thread lesen lässt.

    Der Nutzer ist noch voll aktiv, und hat einen Avatar und ein Profil, welches eindeutig auf diesen Thread hinweist. Er ist sich dessen also bewusst. Das Projekt muss überhaupt nicht tot sein.

  • Threads mit 3 Monaten Inaktivität sperren

    • minx
    • 4. November 2012 um 17:31

    Der Thread ist nicht alt. Es ist ein großes Projekt, der Nutzer ist aktiv und wirbt immer noch dafür. Du weißt nicht ob es noch entwickelt wird.

  • UDF für E-Mail Benachrichtigung

    • minx
    • 4. November 2012 um 15:09

    TCP.

    Du kannst dich per TCP ganz einfach mit deinem Mailserver verbinden und deine Emails abrufen. Voraussetzung: POP3 Konto.

    Hier ist ein Tut mit den Commands: http://smanage.tripod.com/tel.html


    Folgendes ist denkbar:

    Client: Connect with pop.web.de, Port 110 (telnet pop.web.de 110 oder TCPConnect)
    Server: +OK POP SERVER WEB.DE BEREIT (oder so ähnlich)
    Client: USER user@web.de
    Server: +OK Bitte Passwort angeben (oder so)
    Client: PASS apfelstück13
    Server: +OK 2 neue Nachrichten für user@web.de (oder was auch immer dein Anbieter jetzt anzeigt. Das musst du wissen!)


    Oder du nutzt die POP.au3. Aber so geht es auch, und du brauchst kein Include.

  • autoIT OS 3 - Das (kleine) Betriebssystem => Mitentwickler gesucht !!!

    • minx
    • 4. November 2012 um 12:36

    Dieser Thread ist komplett nicht nachvollziehbar.

    Du machst in deinem Profil und Avatar für diesen Thread Werbung, und dann steht hier absolut nichts drin. Kein Startpost, kein Nichts, was man sich anschauen kann. Auf deiner "Website" findet man außer ner billigen Flirtwerbung auch nichts zu dem Skript, welches es ja gar nicht mehr gibt :?:

    Schreib doch mal einen Startpost, oder lass ihn wiederherstellen, und dann kommen da alle Infos rein, ob wie wann und wo das Projekt gerade läuft. So ist es wirklich nur zusammengewürfelt.

    PS: AutoIt, nicht autoIT


    EDIT BugFix

    [CLOSED] wegen Sinnlosigkeit, da kein themenrelevanter Inhalt mehr vorhanden.

  • Code von C auf Autoit konventieren

    • minx
    • 4. November 2012 um 12:27

    Ist da in Zeile 30 nicht ein Komma zu viel am Ende?

  • iUser - Wenn du den Benutzer kontrollieren willst

    • minx
    • 1. November 2012 um 23:31

    Ist kein Bot. Das wärs ja noch, Verwaltungsprogramme als Bots einzustufen.

    Benutzen würde ich es trotzdem nicht, da es eher ein Zwischending zwischen Benutzeraccountverwaltung und CMD ist. Bei mir sind ebenfalls die NET Commands gesperrt, daher für mich nutzlos.

    Aber immer gut, wenn es wenigstens funktioniert :D

  • Wiki Live Search - the easiest way

    • minx
    • 1. November 2012 um 22:37

    Oder nur Suchbegriff. Eigentlich erscheint immer zuerst der WikiArtikel. Und man profitiert noch vom Google AutoKorrekt.

  • Make-Grafik hat Geburtstag!

    • minx
    • 1. November 2012 um 16:35

    Alles gute du Chaot :P

  • GUICtrlCreatePic und Wine

    • minx
    • 1. November 2012 um 16:14

    Bei mir funktioniert es.

  • AutoIt mit Ubuntu 12.X und OSX Lion

    • minx
    • 30. Oktober 2012 um 22:47

    Ich habe mal ausgiebig getestet.

    Unter 12.10 funktioniert 3D Rendering mit OpenGl! :party:

  • _IE Programm mit unabhäniger Session

    • minx
    • 30. Oktober 2012 um 01:08

    -> Auf gelöst setzen bitte.

  • AutoIt mit Ubuntu 12.X und OSX Lion

    • minx
    • 29. Oktober 2012 um 22:12

    Installation?

    Ubuntu:

    Für 12.04 LTS und 12.10 folgende Schritte unternehmen:

    • Alles Updaten
    • Im Softwarecenter WINE (Weinglas Icon), und WINE Layer installieren (einfach nach >wine< suchen)
    • Rechtsklick auf die Installationsexe -> Mit anderer Anwendung öffnen -> Wine Starter
    • Fertig

    OSX Lion:

    • WinOnX installieren (Wine Container)
    • AutoIt installieren

    Was geht?
    Unter Ubuntu alles außer OGl, DirectX, DirectDraw, native Windows-Objekte. GDI+ sollte gehen.
    Unter OSX alles. Für Grafik NUR Graphics, manchmal GDI+, sonst nichts.

  • Mehrere Edits und ES_WANTRETURN

    • minx
    • 27. Oktober 2012 um 18:51

    Das ist nicht so einfach, da ich den Pfeiltasten keine anderen Accelerators mehr zuweisen kann :D. Aber ich habe da eine Idee, danke ;)

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™