Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Korowai

unregistriert

1

05.02.2015, 22:28

Funktion zur Tastatur in GLUT

Hi,

ich habe ein Problem. Ich weiß, dass ich bei einem Funktionsaufruf einen Fehler mache, nur weiß ich nicht, wie ich diesen beheben kann.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void displaystart()

{
    
    keyOperations();
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);
    glTranslatef(0.0f, 0.0f, -5.0f);
    renderBitmapString(0, 0, (void *)font, "Taste zum Starten");
    renderBitmapString(-5.1, 2.5, (void *)font, "Open GL");
    Rahmen();
    while (true)
        {
        if (startvar == 0)
        continue;
        if (startvar == 1)
            break;
        }
    setOrthographicProjection();
    glPushMatrix();
    glLoadIdentity();

    glPopMatrix();
    resetPerspectiveProjection();
    glutSwapBuffers();

    glLoadIdentity();
    glFlush();
    
}


Wie man sieht, habe ich hier eine Endlosschleife, die den Wert einer const int Variable startvar abfragt. Dieser soll sich bei Drücken einer Taste über eine GLUT Keyboardabfrage ändern.
Problem 1: DIe Schleife beeinhaltet keine Tastaturabfrage, ergo keine Änderung der Variable. Wenn ich die Keyboardabfrage einbaue, meldet mir der COmpiler, dass die Funktionen nicht bekannt sind =

Fehler 1 error C2065: 'keyPressed': nichtdeklarierter Bezeichner e:\tutorials_opengl\swiftless_tutorials\2_1\swiftless_2_1\swiftless_2_1\main.cpp 171 1 Swiftless_2_1

Ich habe mich schon im Anfängerstatus mit Funktionen beschäftigt, weiß aber nicht, wie ich es angehen kann. Irgendwie müsste ich es schaffen, innerhalb der Funktion für die Tastaturabfrage einen Rückgabewert für die startvar zu erzeugen. DIese Funktionen haben aber als RÜckgabe bereits die bool des keystates.

Ich weiß nicht mehr so ganz weiter, und google schweigt sich aus...

2

05.02.2015, 22:34

Der Compiler sagt, dass er keyPressed nicht kennt, was das jetzt ist bzw. wo es fehlt geht aus deinem Listing nicht hervor, da es dort nirgends auftaucht
BTW: Sicher dass du ein const int verändern willst? ;)
"Wer Angst hat, dass ihm seine Ideen geklaut werden, der scheint nicht viele zu haben. "

Korowai

unregistriert

3

05.02.2015, 22:39

Hi,

ich poste mal die Funktion:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
void keyPressed(unsigned char key, int x, int y)
{
    keyStates[key] = true;
    if (startvar == 0)
    {
        if ((keyStates['\33']) || (keyStates['a']))
        {
            startvar = 1;
        }
        else
        {
            startvar = 1;
        }
        return;
    }

    else if (startvar == 1)
    {
        if (keyStates['y'])
        {
            if (richtungp1 = 0)
            {
                richtungp1 = 3;
            }
            else if (richtungp1 = 1)
            {
                richtungp1 = 0;
            }
            else if (richtungp1 = 2)
            {
                richtungp1 = 1;
            }
            else if (richtungp1 = 3)
            {
                richtungp1 = 2;
            }

        }
        if (keyStates['x'])
        {
            if (richtungp1 = 3)
            {
                richtungp1 = 0;
            }
            if (richtungp1 = 2)
            {
                richtungp1 = 3;
            }
            if (richtungp1 = 1)
            {
                richtungp1 = 2;
            }
            if (richtungp1 = 0)
            {
                richtungp1 = 3;
            }
        }
    }
}


Ich habe die Variable zuerst als bool, dann als normale int deklariert. SPäter dann, im schlauen Buch "Der C++ Programmierer" (das ich ernsthaft schätze) stand was von const int drin, dass diese Variablen in jeder Funktion bekannt bleiben. Da habe ich es mal geändert. Aber egal.
Es ist zumindest so, wenn ich startvar am Programmbeginn auf 0 oder 1 setze, laufen die beiden Programmteile. Nur mit der Keyboardabfrage funzt es nicht.

4

05.02.2015, 23:03

Der Fehler ist, dass die Funktion an dem Punkt, wo du sie verw enden möchtest nicht kennt, deklarierst du sie evtl. erst nach ihrem Aufruf?
Und eine Variable, die überall bekannt ist, ist global, aber nicht konstant ;)

Konstante Variablen können, wie der Nam schon sagt, nachträcglich nicht verändert werden.
"Wer Angst hat, dass ihm seine Ideen geklaut werden, der scheint nicht viele zu haben. "

Korowai

unregistriert

5

06.02.2015, 09:19

Habe die Endlosschleife in die main verlagert.

Aber die Keyboardabfrage liefert für startvar die 1 zurück, da das Programm weiter läuft. Seltsam, selbst wenn ich alle Funktionsteile auf startvar=0 umstelle. Es bleibt festzustellen, dass die void keyOperations den Wert startvar== 1 liefert, auch wenn keine Taste gedrückt wird.
MMn hat das was mit der if / else Abfrage zu tun. Das die den Wert 1 hat, ist ja auch gut so, aber halt erst, wenn eine Taste gedrückt wird.
An sich müsste ich anstatt einem einfachen else doch eher einen Array abfragen, der alle Tasten umgreift?

main:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitWindowSize(1600, 900);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("OPEN TRON");
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyPressed);
    glutKeyboardUpFunc(keyUp);
    glutSpecialFunc(keySpecial);
    glutSpecialUpFunc(keySpecialUp);
    glutDisplayFunc(displaystart);
    while (true)
    {
        keyOperations();
            if (startvar == 0)
                continue;
            if (startvar == 1)
                break;
        
    }
    glutDisplayFunc(display);
    glutTimerFunc(25, update, 0);
    glutMainLoop();
}



Die displaystart:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void displaystart()

{
    
    keyOperations();
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);
    glTranslatef(0.0f, 0.0f, -5.0f);
    renderBitmapString(0, 0, (void *)font, "Taste -a- zum Starten");
    renderBitmapString(-5.1, 2.5, (void *)font, "Open Tron");
    Rahmen();
    
    setOrthographicProjection();
    glPushMatrix();
    glLoadIdentity();

    glPopMatrix();
    resetPerspectiveProjection();
    glutSwapBuffers();

    glLoadIdentity();
    glFlush();
    
}


Und die Keyabfrage:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
void keyOperations()
{

    if (startvar == 0)
    {
        if ((keyStates['\33']) || (keyStates['a']))
        {
            startvar = 1;
        }
        else
        {
            startvar = 1;
        }
        return;
    }
    
    else if (startvar == 1)
    {
        if (keyStates['y'])
        {
            if (richtungp1 = 0)
            {
                richtungp1 = 3;
            }
            else if (richtungp1 = 1)
            {
                richtungp1 = 0;
            }
            else if (richtungp1 = 2)
            {
                richtungp1 = 1;
            }
            else if (richtungp1 = 3)
            {
                richtungp1 = 2;
            }

        }
        if (keyStates['x'])
        {
            if (richtungp1 = 3)
            {
                richtungp1 = 0;
            }
            if (richtungp1 = 2)
            {
                richtungp1 = 3;
            }
            if (richtungp1 = 1)
            {
                richtungp1 = 2;
            }
            if (richtungp1 = 0)
            {
                richtungp1 = 3;
            }
            }
        }
}


Hat jemand eine Idee?

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

6

06.02.2015, 09:52

Du möchtest deine keyOperations-Funktion vielleicht neu schreiben. Sie ergibt stellenweise keinen Sinn und ist viel zu umständlich implementiert.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
    if (startvar == 0)
    {
        if ((keyStates['\33']) || (keyStates['a']))
        {
            startvar = 1;
        }
        else
        {
            startvar = 1;
        }
        return;
    }
Der innere if-else-Block tut nichts. Damit lässt sich der Klotz darauf herunterbrechen:

C-/C++-Quelltext

1
if(!startvar) {startvar=1; return;}

Der Code in Zeile 19-38 verringert im Grunde genommen bloß richtungp1 um 1, modulo 4. Ausgehend davon, dass richtungp1 nur Werte von 0-4 annimmt, lässt sich dieser Code wie folgt herunterbrechen:

C-/C++-Quelltext

1
if(keyStates['y']) {richtungp1 = (richtungp1 - 1) & 0b11;}
Oder auch:

C-/C++-Quelltext

1
if(keyStates['y']) {richtungp1 = (richtungp1 - 1) % 4;}
(Modulo und Bitmaske sind nicht äquivalent, sobald Vorzeichen ins Spiel kommen!)
Jetzt bleibt da noch der Code von Zeile 39-57, in dem anscheinend ein Bug rumsitzt. Es sieht danach aus, als würde dieser if-Block richtungp1 analog zum Vorherigen um 1 erhöhen. Allerdings gibt es da diesen Schnipsel:

C-/C++-Quelltext

1
2
3
4
            if (richtungp1 = 0)
            {
                richtungp1 = 3;
            }
Entweder verstehe ich nicht, was du tun willst, oder aber du hast hier versehentlich dekrementiert statt inkrementiert. Wahrscheinlich aus Copy-Pasta-Gründen. Entsprechend sollte der gesamte Funktionscode wohl eher so aussehen:

C-/C++-Quelltext

1
2
3
4
5
6
7
void keyOperations() {
  if(0 == startvar) {startvar=1; return;}
  else /* if(...) kann man auslassen, wenn startvar nur 1 oder 0 ist. */ {
    if(keyStates['y']) {richtungp1 = (richtungp1 - 1) & 0b11;}
    if(keyStates['x']) {richtungp1 = (richtungp1 + 1) & 0b11;}
  }
} // ::keyOperations()->void


Jetzt ist der Code gleich viel angenehmer zu lesen und damit sind dann auch Bugs leichter zu finden. Genau so lässt sich auch keyPressed herunterbrechen. Und zum Schluss sei noch gesagt, dass ich mir gerade nur vorstellen kann, dass der Compiler-Fehler wohl daher käme, dass die Funktion keyPressed nicht vor main deklariert wurde. Genau weiß ich das nicht, kenne ja nicht deine Header usw.

(P.S.: Du weißt hoffentlich, dass das altes OpenGL1-2 ist, was du da lernst. Ich wusste es nicht, als ich eigentlich GL3+ lernen wollte.)


Edit:
Mir fiel auch eben in der Dusche auf, dass diese Inkrement-if-Kaskaden für X eh' nicht funktioniert hätten, da du if statt else if nutztest. Für richtungp1==3 würde sich nichts ändern.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Evrey« (06.02.2015, 10:42)


Korowai

unregistriert

7

06.02.2015, 16:02

Ich weiß, es ist 2.0

Das Programm baut auf Tutorials auf, die ich im Netz gefunden habe. Bevor ich mich mit den aktuellen Tutorials beschäftige, möchte ich erstmal das hier fertig stellen und es vor allem kapieren.

Es fehlt halt noch ne Menge bei mir.
Zum BEispiel kannte ich

...

Quellcode

1
 & 0b11;}

überhaupt nicht. Was macht dieser Schnipsel?

Ich mache mich mal dran, ganz neu, mit Deinem post sollte es doch hinhauen.
Achso, "keyPressed" ist vor der main deklariert. Daran kanns nicht liegen... aber ich schau mal,
Danke...

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

8

07.02.2015, 16:26

Kein Ding, viel Erfolg. °^°

Der Code-Schnipsel ist ein wenig hackish und nennt sich "Bitmaskierung". 0b11 ist eine Binärzahl, die Hexadezimal 0x3, oder Dezimal 3 entspricht. Das & ist der binäre Und-Operator. Zusammen mit 0b11 sorgt er dafür, dass ich nur die untersten zwei Bits von richtungp1 erhalte, was alle Zahlen von 0 bis 3 filtert, was wiederum dem vorzeichenlosen Modulo 4 entspricht.

Die meisten Compiler erledigen das häufig für dich und ersetzen %4 im Hintergrund durch &3, da die Modulo-Operation 18 bis 48 Takte benötigt, Bit-Und hingegen nur 1 Takt braucht. Der Lesbarkeit halber wird daher nicht selten empfohlen, Modulo zu schreiben.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

9

07.02.2015, 17:04

0b11 wäre eine sehr schlechte Idee, weil es nicht Teil des aktuellen C++ Standards ist und auch nicht von jedem aktuellen Compiler unterstützt wird. Man sollte einfach "3" nehmen. Ich bin auch kein Freund davon alles in eine Zeile zu packen, weil es dann etwas willkürlich wird, wann ein Zeilenumbruch erfolgt und wann nicht. Ich würde eher empfehlen, bei Einzeilern einfach die geschweiften Klammern wegzulassen, aber trotzdem umzubrechen, das hilft meistens genug.

Der ursprüngliche Code ist aber wesentlich länger und komplexer als er sein müsste. Die Anpassungen wären sonst also auf jeden Fall dringend sinnvoll. Dann solltest du ihn auch selbst leicht verstehen können.

Nebenbei:
GLUT ist uralt. Ich würde dir empfehlen, auf Dauer eine neuere Alternative zu nehmen.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Spiele Programmierer« (07.02.2015, 17:12)


Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

10

07.02.2015, 20:28

Zitat

weil es nicht Teil des aktuellen C++ Standards ist
Es ist der aktuelle Standard und wird sowohl von GCC als auch von Clang unterstützt. MSVC interessiert mich nicht, und ältere Compiler interessieren mich noch weniger.

Zitat

die geschweiften Klammern wegzulassen
Ich halte das Auslassen der Klammern für eine stilistische Katastrophe, die in keiner meiner Projekte etwas zu suchen hat.

Zitat

auf Dauer eine neuere Alternative zu nehmen
Ich bin bisher mit der Kombi GLFW und GL Load ganz glücklich.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Werbeanzeige