# C++/OpenGL



## AMD (25. April 2011)

Hey,

Habe eine kleine 3D Anwendung in C++ mithilfe von OpenGL programmiert. Nun habe ich ein kleines Problem mit der Tastatur und hoffe ihr wisst weiter 

1. Es gibt eine Steuerung mit den Pfeiltasten! Doch diese verläuft nicht ganz "flüssig". Drücke ich nun z.B. permanent die Pfeiltaste nach rechts, geht es wie folgt los: Rechts - Pause - Dauerthaft Rechts. (Schwer zu erklären)
Also es kommt halt eine kurze Pause!
Ihr könnt es wiefolgt probieren: Schreibt einfach ein paar Zeichen und drückt dauerhaft die Backspace Taste! Nachdem das erste Zeichen gelöscht wurde, kommt eine Pause und dann gehts normal weiter!
Kann man das dagegen machen?

2. Wenn ich z.B. die Pfeiltaste drücke, und dann einen Buchstaben, wird nur noch der Buchstabe wahrgenommen aber die Pfeiltaste muss dann neu gedrückt werden jedoch geht dann wieder der Buchstabe nicht! Heißt also: Max. 1 Taste auf der Tastatur, wie kann man das Problem lösen?

Hoffe es ist alles verständlich aber auch komisch zu erklären


----------



## Chroma (25. April 2011)

*AW: C++/OpenGL + Tastatur*

Zu 2.: Setz eine bool'sche Variable auf true sobald die Taste gedrückt wird und erst dann wieder auf false, wenn die Taste "losgelassen" wird. Musste mal gucken wie die Befehle dafür in OpenGL heißen. Ich weiß es nicht


----------



## Dragonix (25. April 2011)

*AW: C++/OpenGL + Tastatur*

Wie realisierst du Input? OpenGL kann das nicht, dass musst du ja i-wie mit SDL, (free)GLUT, SFML oder WinAPI/X (etc.) machen. Die Doku zu einer dieser Bibliotheken hilft dir da vermutlich


----------



## AMD (26. April 2011)

*AW: C++/OpenGL + Tastatur*

@Chroma: Ich teste es mal obs funktioniert.

@Dragonix: Ja (free)GLUT 
Aber so ganz schlau bin ich nicht draus geworden


----------



## AMD (26. April 2011)

*AW: C++/OpenGL + Tastatur*

Naja hat nicht so ganz geklappt - hoffe gibt noch andere Ideen!

Außerdem hätte ich noch eine Frage zur Maus. Wie kann ich die Maus z.B. verschwinden lassen, wenn diese in der Anwendung ist und dann z.B. die aktuellen Koordinaten nehmen damit ich z.B. die Kameraposition verändern kann?


----------



## Dragonix (26. April 2011)

*AW: C++/OpenGL + Tastatur*

Etz schau dir halt mal die Doku zu FreeGLUT an!
Chromas Methode funktioniert einwandfrei: Mit glutKeyboardFunc registrieren wenn eine Taste gedrückt wurde, und durch glutKeyboardUpFunc bekommst du mit, wann eine Taste wieder freigegeben wird.
Beispiel Funktionen (nicht vergessen, über glutKeyboardFunc bzw glutKeyboardUpFunc registrieren):

```
char keyboard[256];  //Initialisieren!

void KeyboardFunc(unsigned char key, int x, int y)
{
if(key == 'w')
  keyboard['w'] = 1; //Taste w ist jetzt gedrückt
}

void KeyboardUpFunc(unsigned char key, int x, int y)
{
if(key == 'w')
  keyboard['w'] = 0; //Taste w ist jetzt nicht mehr gedrückt
}
```
Und bei jedem rendern musst du dann halt die Tasten verarbeiten.. z.B. so

```
void VerarbeiteTasten(unsigned int vergangeneZeit) //vergangeneZeit ist die Zeit seit dem letzten Aufruf der Funktion
{
  float schritt = 0.1f;
  float deltaZ = keyboard['w'] * schritt * vergangeneZeit;

  //code um deltaZ zu verarbeiten (Matrix, Objektposition, oder was auch immer anpassen)
}
```
Mauszeiger wegmachen: In die Doc gucken, oder bei google der erste Treffer:

```
glutSetCursor (GLUT_CURSOR_NONE);
```

So in etwa, nur als Anregung 
Edit: Für die Spezialtasten (dazu gehören auch die Pfeiltasten): glutSpecialFunc bzw glutSpecialUpFunc!


----------



## AMD (26. April 2011)

*AW: C++/OpenGL + Tastatur*

Hm okay muss ich nochmal probieren mit den Tasten 

glutSetCursor hab ich schon gefunden sowie glutSpecialFunc für Pfeiltasten habe ich schon.
Irgendwie habe ich nur das Problem die aktuelle Mausposition zu bekommen...
Als ich gegooglet habe, fand ich entweder nur Codes wo man eine neue Mausposition setzen kann oder halt ich bekomme die X und Y Werte mithilfe der glutMotionFunc zurück allerdings nur dann, wenn ich auch eine Taste drücke (z.B. linke Maustaste)... habs per frametime checken lassen aber ging nur wenn Tastendruck 

Sorry wegen meinen doofen Fragen, kann zwar ganz ordentlich C++ aber in Sachen OpenGL/Glut bin ich noch recht neu unterwegs  

Aber nichts desto trotz: Danke für eure Hilfe!


----------



## Dragonix (26. April 2011)

*AW: C++/OpenGL + Tastatur*

Hm.. also wenns dir bei Bewegung ausreicht.. glutPassiveMotionFunc, wird bei jeder Bewegung aufgerufen (also auch ohne Klick).
Kannst dir das mal anschauen, evtl was für dich? Index » Lighthouse3d.com


----------



## AMD (26. April 2011)

*AW: C++/OpenGL + Tastatur*

Ich schau mir das morgen mal an... eig. meinte ich auch "glutMouseFunc" und nicht Motion 

Edit// Habs mir jetzt schon angeguckt: Das sollte weiterhelfen! Danke  Die MotionFunc hilft da wohl auch


----------



## AMD (27. April 2011)

*AW: C++/OpenGL + Tastatur*

So habs mir angeguckt und eine gute Lösung gefunden  Funktioniert nun alles, wenn auch ein wenig anders als auf der Seite!
Hätte allerdings noch eine Frage, bei google wurde ich nicht so gut fündig...

Gibt es ein simples Objektformat, was ich relativ einfach einbinden kann und es auch gleich ein exportscript für 3ds max oder ähnlichem gibt?
Möchte ja eig. ein paar Dinge mit Grafik probieren - also eher spielerein  - und ein Objektformat selber machen finde ich recht aufwendig und denke mal, es wird schon was geben nur ich weiss nicht genau wo und welches zu empfehlen ist! Hoffe ihr wisst da mehr


----------



## AMD (27. April 2011)

*AW: C++/OpenGL + Tastatur*

*nochmal hochschieb*

Hab mich nunmal selber REICHLICH mit dem obj Format beschäftigt, was ja ganz gut aussieht doch der Import ist echt ******* 
Mein code liest die Datei aus und ich sehe auch das Objekt quasi gerendert doch nunja, die polys sind nicht wirklich miteinander verbunden! Aber am besten ich zeig euch erstmal was ich meine:




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Hier der Source:

```
void LoadObjects()
{
    ifstream obj;
    string obj_str;
    float Vektor[9999][3];
    float x, y, z;
    int counter = 0;
    int i = 0;
    obj.open("box.obj", ios::in);
        while (!obj.eof())
        {
            getline(obj, obj_str);
            size_t pos = obj_str.find("v  ");
            if (pos == 0) {
                sscanf(obj_str.c_str(), "v  %f %f %f", &x, &y, &z);
                Vektor[i][0] = x;
                Vektor[i][1] = y;
                Vektor[i][2] = z;
                i++;
                counter++;
            };
        };
        obj.close();

        int j = 0;
        while (j <= counter)
        {
            glBegin(GL_TRIANGLES);
                j++;
                glVertex3f(Vektor[j][0], Vektor[j][1], Vektor[j][2]);
                j++;
                glVertex3f(Vektor[j][0], Vektor[j][1], Vektor[j][2]);
                j++;
                glVertex3f(Vektor[j][0], Vektor[j][1], Vektor[j][2]);
            glEnd();    
        };
}
```
Hoffe ihr könnt mir weiterhelfen.

*Edit//* Okay habs selber hinbekommen!


----------



## AMD (30. April 2011)

*AW: C++/OpenGL + Tastatur*

Ich nehm einfach mal meinen Thread weiter. 

Jedenfalls werden die Objekte nun komplett gerendert und Texturen werden auch korrekt importiert doch leider habe ich ein Problem mit der Kamerasteuerung!
Ich nehme folgenden Befehl: gluLookAt()
welcher wiefolgt aufgebaut ist: 

```
gluLookAt(Kamera Position, Zielkoordinaten wo hingeguckt wird | Einheitsvektor);
```


```
float Einheitsvektor(float v1, float v2, float v3)
	float m = sqrt(v1 * v1 + v2 * v2 + v3 * v3);
	return (v1/m), (v2/m), (v3/m);
}
```

Mit den Pfeiltasten bewege ich mich im Raum, was super klappt.. das mache ich wie folgt:

```
gluLookAt(Move_x, Move_y, 1.8f, Move_x + 1.0f, Move_y + 1.0f, 1.8f, 1, 1, 1);
```

Leider müsste man noch die Mausbewegung mit einrechnen, damit ich mich zum einen umschauen kann (bekomme ich eig. schon hin) nur das Problem ist, wenn ich z.B. 45° nach rechts schaue, und Pfeil nach oben drücke, wendet die Kamera nicht mit 45° nach rechts sondern geht stur weiter gerade aus! Da bin ich mir leider nicht ganz sicher wie ich das Problem mathematisch lösen soll...
Hoffe mir kann da jmd. weiterhelfen


----------



## Dragonix (30. April 2011)

Evtl hilft dir das?
Tutorial Kamera1


```
float Einheitsvektor(float v1, float v2, float v3)
	float m = sqrt(v1 * v1 + v2 * v2 + v3 * v3);
	return (v1/m), (v2/m), (v3/m);
}
```
Das ist übrigens auch nicht das von dir gewünschte. Zumindest wenn du alle 3 Werte haben möchtest. Aber so bekommst du nur (v3/m) zurück!


----------



## AMD (1. Mai 2011)

Das mit der Kamera les Ich mir mal durch, könnte helfen! 

Die Funktion sollte eher Pseude sein! Im richten Programm kommen 3 Werte zurück 


Kleine Frage am Rande (mal wieder): Gibts eine einfache Möglichkeit in C++ Abstand Punkt-Ebene zu berechnen? Müsste auch erst von Parameterform in Koordinatenform umgerechnet werden... gerade der Algorithmus sieht recht kompliziert aus zu programmieren


----------



## Bauer87 (1. Mai 2011)

Abstand: Der Abstand _d_ eines Punktes von einer Ebene ist _d_ = (*x*-*s*)·*n*, wobei *s* ein Punkt auf der Ebene ist, *n* der Normaleneinheitsvektor und *x* der zu überprüfende Punkt. Geht ganz einfach und schnell.


----------



## AMD (1. Mai 2011)

Hm ich bin noch etwas unschlüssig (ich sollte mir echt mal gefühlte 5 Mathebücher durchlesen  )

Sagen wir mal ich habe folgende Werte: 
A (1,1,1)
B (5, 3, 1)
C (3, 5, 2)

Der Punkt P ist einfach mal (5, 5, 5).
Jetzt müsste man doch eine Ebene erstellen.
Dazu einfach erstmal:
       1        4       2
x = (1) +r(2) +s(4)
       1       0        1

RIchtungsvektor R = B - A | S = C - A
Denke das sollte stimmen.
Nur jetzt das alles in eine Ebene zu bringen (das man quasi nur noch eine Zeile hat) gelingt mir nicht! Klar kann ich das auf dem Papier ausrechnen aber einen Algorithmus schreiben der mir das ausrechnet in C++.
Hättest du da vllt. noch eine Lösung/Ansatz?

Edit// Formatierung ist auch nicht gerade genial...
die 1 4 2 müssten halt über die jeweile Zahl stehen (1) (2) (4) - das gleiche gilt für 1 0 1


----------



## Bauer87 (1. Mai 2011)

Du brauchst die Ebene in Normalenform. Das Schlagwort dazu heißt je nach Literatur Kreuzprodukt,  Vektorprodukt oder inneres Produkt. Der Trick ist, dass das innere Produkt zweier Vektoren ein Vektor ist, der senkrecht auf diesen beiden steht. Außerdem sollte man wissen, dass das äußere Produkt (aka Skalarprodukt) die Länge der Projektion eines der Vektoren auf den anderen berechnet. Wenn man ein Lot auf eine Ebene hat, wäre das also der Abstand.


----------



## AMD (2. Mai 2011)

Bauer87 schrieb:


> Du brauchst die Ebene in Normalenform. Das Schlagwort dazu heißt je nach Literatur Kreuzprodukt,  Vektorprodukt oder inneres Produkt. Der Trick ist, dass das innere Produkt zweier Vektoren ein Vektor ist, der senkrecht auf diesen beiden steht. Außerdem sollte man wissen, dass das äußere Produkt (aka Skalarprodukt) die Länge der Projektion eines der Vektoren auf den anderen berechnet. Wenn man ein Lot auf eine Ebene hat, wäre das also der Abstand.


 Danke für die Hilfe, hat geklappt 

Nur mit der Kameranutzung bin ich mir nach wie vor nicht ganz schlüssig, was da die Beste Umsetzung ist aber am besten ich fang die Tage nochmal bei 0 an und les mir alle Basics dazu durch


----------

