Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SDL2 OpenGL C++;移动使用VBO和FBO绘制的精灵_C++_Opengl_Sdl 2 - Fatal编程技术网

C++ SDL2 OpenGL C++;移动使用VBO和FBO绘制的精灵

C++ SDL2 OpenGL C++;移动使用VBO和FBO绘制的精灵,c++,opengl,sdl-2,C++,Opengl,Sdl 2,我使用fbo和vbo在我的Sprite.cpp中绑定并绘制了一个由两个三角形组成的矩形,下面是我的init方法 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

我使用fbo和vbo在我的Sprite.cpp中绑定并绘制了一个由两个三角形组成的矩形,下面是我的init方法

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);
}

这是画法

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);
}

很明显,我遗漏了一些非常明显的概念,因为我似乎在任何地方都找不到解决方案,我的问题是当我按下s时,我的矩形没有向下移动。(因为我使用的是WASD移动)下面是输入处理程序的代码

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);
    }
}

}
void InputHandler::handleInput(SDL_事件*事件,精灵*移动){
开关(事件->类型){
案例SDL_按键关闭:
{
if(事件->key.keysym.sym==SDLK\u a){
toMove->setMovementBooleans(MovementTuples::LEFT,true);
std::cout key.keysym.sym==SDLK\u d){
toMove->setMovementBooleans(MovementTuples::RIGHT,true);
std::cout key.keysym.sym==SDLK\u s){
toMove->setMovementBooleans(MovementTuples::DOWN,true);
std::cout key.keysym.sym==SDLK\u w){
toMove->setMovementBooleans(MovementTuples::UP,true);
std::cout key.keysym.sym==SDLK_a){
toMove->setMovementBooleans(MovementTuples::LEFT,false);
}
if(事件->key.keysym.sym==SDLK\u d){
toMove->setMovementBooleans(MovementTuples::RIGHT,false);
}
if(事件->key.keysym.sym==SDLK\u s){
toMove->setMovementBooleans(MovementTuples::DOWN,false);
}
if(事件->key.keysym.sym==SDLK\u w){
toMove->setMovementBooleans(MovementTuples::UP,false);
}
}
}
}

此方法是静态访问的。以下是在“我的精灵cpp”中单击s键时向下移动精灵的代码

void Sprite::update() {

if (movementBooleans[MovementTuples::DOWN]) {
    _x -= .1f;
    init(_x, _y, _width, _height);
    std::cout << "Moved to: (" << _x << ", " << _y  << ")"<<  std::endl;
}
void Sprite::update(){
if(movementBooleans[MovementTuples::DOWN]){
_x-=.1f;
初始值(x,y,宽度,高度);

我使用的是OpenGL。虽然我没有使用SDL,因为我使用的是用户实现的输入处理程序,但概念应该是相同的

我当前使用的游戏引擎有一个游戏类对象,该对象继承自引擎类对象,其中引擎类是一个单例对象。由于此游戏引擎的结构,引擎类需要游戏类实现虚拟键盘输入功能。以下是原型的外观

发动机等级

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
class Game sealed : public Engine {
private:
    // private members here

public:
    // Constructor and virtual Destructor

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

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
class Game sealed : public Engine {
private:
    // private members here

public:
    // Constructor and virtual Destructor

private:
   virtual void keyBoardInput( unsigned vkCode, bool isPressed ) override;
}; // Game
下面是适用于Windows的messageHandler()函数

// ----------------------------------------------------------------------------
// 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
最后是keyboardInput()函数

//----------------------------------------------------------------------------
//键盘输入()
void Game::键盘输入(未签名的vkCode,bool-isPressed){
std::ostringstream strStream;

strStream我使用的是OpenGL。虽然我没有使用SDL,因为我使用的是用户实现的输入处理程序,但概念应该是相同的

我当前使用的游戏引擎有一个游戏类对象,该对象继承自引擎类对象,其中引擎类是一个单例对象。由于此游戏引擎的结构,引擎类需要游戏类实现虚拟键盘输入功能。以下是原型的外观

发动机等级

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
class Game sealed : public Engine {
private:
    // private members here

public:
    // Constructor and virtual Destructor

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

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
class Game sealed : public Engine {
private:
    // private members here

public:
    // Constructor and virtual Destructor

private:
   virtual void keyBoardInput( unsigned vkCode, bool isPressed ) override;
}; // Game
下面是适用于Windows的messageHandler()函数

// ----------------------------------------------------------------------------
// 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
最后是keyboardInput()函数

//----------------------------------------------------------------------------
//键盘输入()
void Game::键盘输入(未签名的vkCode,bool-isPressed){
std::ostringstream strStream;

strStream如果你想移动OpenGL图形,你真的应该做矩阵变换


我个人使用GLM为我完成所有繁重的工作,因此我所要做的就是在转换完成后将矩阵传递到GLSL。

如果你想移动OpenGL图形,你真的应该进行矩阵转换


我个人使用GLM为我完成所有繁重的工作,所以我所要做的就是在变换完成后将矩阵传递到GLSL。

+1为了努力,但这与我的问题毫无关系,是的,我知道你在做什么,但我的问题是如何移动我的精灵…我的输入工作。从你向我描述的内容来看:“
…,我的问题是当我按下s键时,我的矩形没有向下移动…”
“然后你显示了你的
inputHandler()
的逻辑,然后你继续说,“
当我按下时,我的矩形完全消失,x值保持不变;…
”这个行为听起来像是重复按下了这个键
尝试使用从
0.1f
0.05f
的较小值,而不是修改
\ux
变量,将其替换为
\uy
。如果要垂直移动它,请增加和减少向量的y分量。您还没有显示调用这些函数的代码。我希望它触发contin就像这样,我把它放到了0.00001f,它在我的messageHandler中做了同样的事情,我要做的就是注释掉这段代码:
if(0==(lParam&0x40000000)){//superss key Repeats keyboardInput(wParam,true);}
因为这会抑制多个关键动作。+1表示努力,但这实际上与我的问题无关,是的,我知道你在做什么,但我的问题是如何移动我的精灵…我的输入工作。根据你对我的描述:“
,我的问题是当我按下s时,我的矩形不会向下移动…”
”然后你展示了你的
inputHandler()
的逻辑,然后你继续说,“
当我点击下时,我的矩形完全消失,x值保持不变,…
”,行为听起来就像是重复按下键。在你的
Sprite::update()中
尝试使用从
0.1f
0.05f
的较小值,而不是修改
\ux
变量