2016-08-08 38 views
0

I eine Fbo und VBO verwendet zu binden und ein Rechteck zu zeichnen meine Sprite.cpp bestehend aus zwei Dreiecke int, hier ist meine Methode InitSDL2 OpenGL ++ C ein Sprite gezeichnet mit VBO und FBO beweglichen

void Sprite::init(float x, float y, float width, float height) { 

_x = x; 
_y = y; 
_width = width; 
_height = height; 

if (_vboID == 0) { 

    glGenBuffers(1, &_vboID); 

} 



vertexData[0] = x + width; 
vertexData[1] = y + height; 

vertexData[2] = x; 
vertexData[3] = y + height; 

vertexData[4] = x; 
vertexData[5] = y; 

vertexData[6] = x + width; 
vertexData[7] = y + height; 

vertexData[8] = x; 
vertexData[9] = y; 

vertexData[10] = x + width; 
vertexData[11] = y; 


glBindBuffer(GL_ARRAY_BUFFER, _vboID); 

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_DYNAMIC_DRAW); 

glBindBuffer(GL_ARRAY_BUFFER, 0); 

}

und hier ist das Streck-Verfahren

void Sprite::draw() { 

glBindBuffer(GL_ARRAY_BUFFER, _vboID); 
glEnableVertexAttribArray(0); 


glVertexAttribPointer(0, 2, 0x1406, GL_FALSE, 0, 0); 
glDrawArrays(GL_TRIANGLES, 0, 6); 

glDisableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

}

ich klar einig sehr offensichtlich co bin fehle ncept, weil ich nirgends die Lösung finden kann, ist mein Problem, wenn ich s drücke, bewegt sich mein Rechteck nicht nach unten. (S, weil ich WASD Bewegung bin mit) Hier ist der Code für den Eingang Handler

void InputHandler::handleInput(SDL_Event* event, Sprite *toMove) { 

switch (event->type) { 

case SDL_KEYDOWN: 
{ 
    if (event->key.keysym.sym == SDLK_a) { 
     toMove->setMovementBooleans(MovementTuples::LEFT, true); 
     std::cout << "Set left "; 
    } 
    if (event->key.keysym.sym == SDLK_d) { 
     toMove->setMovementBooleans(MovementTuples::RIGHT, true); 
     std::cout << "Set right "; 
    } 
    if (event->key.keysym.sym == SDLK_s) { 
     toMove->setMovementBooleans(MovementTuples::DOWN, true); 
     std::cout << "Set down "; 
    } 
    if (event->key.keysym.sym == SDLK_w) { 
     toMove->setMovementBooleans(MovementTuples::UP, true); 
     std::cout << "Set up "; 
    } 
    break; 

} 

case SDL_KEYUP: 
{ 
    if (event->key.keysym.sym == SDLK_a) { 
     toMove->setMovementBooleans(MovementTuples::LEFT, false); 
    } 
    if (event->key.keysym.sym == SDLK_d) { 
     toMove->setMovementBooleans(MovementTuples::RIGHT, false); 
    } 
    if (event->key.keysym.sym == SDLK_s) { 
     toMove->setMovementBooleans(MovementTuples::DOWN, false); 
    } 
    if (event->key.keysym.sym == SDLK_w) { 
     toMove->setMovementBooleans(MovementTuples::UP, false); 
    } 
} 

} 

}

Diese Methode ist statisch zugegriffen. Hier ist der Code für die Bewegung des Sprite nach unten, wenn Sie die Taste s in meinem Sprite cpp klicken

void Sprite::update() { 

if (movementBooleans[MovementTuples::DOWN]) { 
    _x -= .1f; 
    init(_x, _y, _width, _height); 
    std::cout << "Moved to: (" << _x << ", " << _y << ")"<< std::endl; 
} 

Wenn ich auf dich, mein Rechteck vollständig verschwinden und die _x Wert bleibt gleich. Ich habe die Eingabe getestet und es funktioniert genau so, wie ich es möchte, ich kann das Rechteck nicht bewegen. Kann mir jemand helfen, meinen Sprite zu bewegen, danke!

Antwort

1

Ich verwende OpenGL. Obwohl ich SDL nicht verwende, da ich die implementierten Eingabehandler eines Benutzers verwende, sollte das Konzept dasselbe sein.

Die Game-Engine, die ich derzeit verwende, hat ein Game-Klassenobjekt, das von einem Engine-Klassenobjekt geerbt wird, wobei die Engine-Klasse ein Singleton-Objekt ist. Aufgrund der Struktur dieser Game Engine; Die Engine-Klasse benötigt die Game-Klasse, um eine virtuelle keyboardInput-Funktion zu implementieren. Hier ist, was der Prototyp sieht aus wie

Engine Class

class Engine : public Singleton { 
protected: 
    // Protected Members 
private: 
    // Private Members 

public: 
    // virtual destructor & public functions 
protected: 
    // explicit protected Constructor & protected functions 
private: 
    bool messageHandler(unsigned uMsg, WPARAM wParam, LPARAM lParam); 

    virtual void keyboardInput(unsigned vkCode, bool isPressed) = 0; 

    // Other Private Functions 

}; // Engine 

Spielklasse

class Game sealed : public Engine { 
private: 
    // private members here 

public: 
    // Constructor and virtual Destructor 

private: 
    virtual void keyBoardInput(unsigned vkCode, bool isPressed) override; 
}; // Game 

hier die message ist() Funktion für Windows

// ---------------------------------------------------------------------------- 
// messageHandler() 
bool Engine::messageHandler(unsigned uMsg, WPARAM wParam, LPARAM lParam) { 
    switch(uMsg) { 
     case WM_CLOSE: { 
      PostQuitMessage(0); 
      return true; 
     } 
     case WM_SYSKEYDOWN : { 
      if ((VK_MENU == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RMENU; // Alt Key 
      } 
      // Fall Through 
     } 
     case WM_KEYDOWN: { 
      if ((VK_RETURN == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_SEPARATOR; 

      } else if ((VK_CONTROL == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RCONTROL; 
      } 

      if (0 == (lParam & 0x40000000)) { // Supress Key Repeats 
       keyboardInput(wParam, true); 
      } 
      return true; 
     } 
     case WM_SYSKEYUP: { 
      if ((VK_MENU == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RMENU; // Alt Key 
      } 
      // Fall Through 
     } 
     case WM_KEYUP: { 
      if ((VK_RETURN == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_SEPARATOR; 

      } else if ((VK_CONTROL == wParam) && (lParam & 0x1000000)) { 
       wParam = VK_RCONTROL; 
      } 

      keyboardInput(wParam, false); 

      return true; 
     } 
     case WM_MOUSEMOVE: { 
      // Mouse Motion Detected, Coordinates Are WRT Window Therefore 
      // 0,0 Is The Coordinate Of The Top Left Corner Of The Window 
      m_mouseState.position = glm::ivec2(LOWORD(lParam), HIWORD(lParam)); 
      mouseInput(); 
      return true; 
     } 
     case WM_LBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_LEFT_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_LBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_LEFT_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_RBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_RIGHT_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_RBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_RIGHT_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_MBUTTONDOWN: { 
      m_mouseState.isButtonPressed[MOUSE_MIDDLE_BUTTON] = true; 
      mouseInput(); 
      return true; 
     } 
     case WM_MBUTTONUP: { 
      m_mouseState.isButtonPressed[MOUSE_MIDDLE_BUTTON] = false; 
      mouseInput(); 
      return true; 
     } 
     case WM_MOUSEWHEEL: { 
      // Mouse Wheel Moved 
      // wParam Contains How Much It Was Moved 
      return true; 
     } 
     default: { 
      return false; // Did Not Handle The Message 
     } 
    } 
} // messageHandler 

schließlich t sein ist die Tastatureingabe() Funktion

// ---------------------------------------------------------------------------- 
// keyboardInput() 
void Game::keyboardInput(unsigned vkCode, bool isPressed) { 
    std::ostringstream strStream; 
    strStream << "Key 0" << std::hex << vkCode << " was " << (isPressed ? "Pressed" : "Released"); 
    Logger::log(strStream); 

    if (VK_ESCAPE == vkCode) { 
     PostQuitMessage(0); 
    } 

    static bool keyPressed[256] = { 0 }; 
    if (vkCode < 256) { 
     keyPressed[vkCode] = isPressed; 
    } 

    if (isPressed) { 
     return; 
    } 

    switch (vkCode) { 
     case VK_DOWN: 
     case 'S' : { 
      // do logic here 
      break; 
     } 
     case VK_LEFT: 
     case 'A' : { 
      // do logic here 
      break; 
     } 
     case VK_RIGHT: 
     case 'D' : { 
      // do logic here 
      break; 
     } 
     case VK_UP: 
     case 'W' : { 
      // do logic here 
      break; 
     } 
    } 

} // handleKeyboard 

Wenn Sie genau auf den Code schauen; Ich werde nicht abfragen, um zu sehen, wann die Taste gedrückt wird, aber ich frage oder warte, um zu sehen, wann die Taste losgelassen wurde. Der Grund für diese Logik ist dies; Wenn Sie eine Taste drücken, kann sie wiederholt gedrückt werden, ohne den Status "hoch" zu drücken. Dies ist, als ob Sie dieselbe Taste in einem beliebigen Texteditor gedrückt halten, wo Sie den gleichen Schlüssel sehen, der auf dem Bildschirm angezeigt wird. Um dies zu umgehen oder um dieses Verhalten zu vermeiden; wir machen die entgegengesetzte Logik.

Wir suchen, wenn der Schlüssel freigegeben wurde. Die Taste kann nur einmal losgelassen werden und muss erneut gedrückt werden, um wieder in den Freigabezustand zu gelangen. Auf diese Weise haben Sie die Aktion des Programms einmal für jeden Tastendruck und dann loslassen.

Jetzt, wenn Sie bemerkt haben, überprüfen wir, ob der Schlüssel in dem gedrückten Zustand ist, und wenn es dann ist, kehren wir zurück; Dies ist wichtig, wenn Sie dies nicht tun, wird Ihr Programm automatisch tun, was innerhalb der Nachrichtenhandler ist, da der Zustand der Tastenbetätigung standardmäßig bereits im freigegebenen Zustand ist. Was also hier passiert, ist entweder während des Renderrahmens oder des Aktualisierungsrahmens, wenn die Funktionen Game::keyboardInput() und Engine::messageHandler() aufgerufen werden und wenn festgestellt wird, dass der Tastendruck seinen Status auf true geändert hat, kehrt er von der Funktion zurück und wird fortlaufend aufgerufen, bis Sie den Befehl loslassen Schlüssel; Sobald der Schlüssel freigegeben wird und der Status wieder in freigegeben geändert wird, überspringt er die if-Anweisung und geht direkt zu der switch-Anweisung, um welchen Schlüssel es sich handelt.

+0

+1 für die Mühe, aber das hat buchstäblich nichts mit meiner Frage zu tun, ja, ich verstehe, was Sie tun, aber meine Frage ist, wie ich mein Sprite bewegen ... meine Eingabe funktioniert. – Luke

+0

Von dem, was du mir beschrieben hast: "' ..., mein Problem ist, wenn ich s drücke, mein Rechteck sich nicht nach unten bewegt. ... "" dann hast du deine Logik für deinen 'inputHandler()' gezeigt, dann gehst du weiter Sagen wir: "Wenn ich herunterklicke, verschwindet mein Rechteck vollständig und der _x-Wert bleibt gleich; ..." "und das Verhalten klingt, als ob die Taste wiederholt gedrückt wird. Versuchen Sie in Ihrem 'Sprite :: update()', einen kleineren Wert von '0.1f' zu' 0.05f' zu verwenden und ersetzen Sie statt '_x' die Variable durch' _y'. Wenn Sie es vertikal verschieben möchten, vergrößern und verkleinern Sie die Y-Komponente Ihres Vektors. –

+0

Sie haben auch nicht den Code angezeigt, in dem Sie diese Funktionen aufrufen. –

1

Sie sollten wirklich Matrixtransformationen durchführen, wenn Sie eine OpenGL-Form verschieben möchten.

Ich persönlich benutze GLM, um das ganze schwere Heben für mich zu machen, also muss ich nur die Matrix in GLSL passieren, nachdem die Transformationen gemacht sind.