【问题标题】:OpenGL - Getting camera to moveOpenGL - 让相机移动
【发布时间】:2018-03-15 21:54:10
【问题描述】:

我的 OpenGL 游戏出现问题,无法让相机移动。

我无法使用 GLFW、GLUT 和 glulookat()。这是我的代码,有什么问题?

P.S 一切正常,除了相机移动意味着游戏可以完美运行,只是不能移动相机。

我的相机代码:

    #include "SpriteRenderer.h"

    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>

    class Camera
{
private:
    Shader shader;

    GLfloat     angle = -90.f;

    glm::vec3   cameraFront = glm::vec3(0.0f, 0.0f, -1.0f),
                cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f),
                cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);

    glm::mat4   viewMatrix;

    // recompute the view matrix from the camera variables
    void updateMatrix()
    {
        viewMatrix = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp);
    }

    // default constructor
    void defaultNew()
    {
        cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f);
        cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
        cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
        updateMatrix();
    }

public:
    Camera() { defaultNew(); }
    Camera(Shader &shader) { this->shader = shader; defaultNew(); }

    glm::mat4 GetViewMatrix() const
    {
        // if your view matrix is always up-to-date, just return it directly
        return viewMatrix;
    }

    // get functions
    glm::vec3 GetCameraPosition() const { return cameraPosition; }
    // .. same for Front and Up

    // set functions
    // call updateMatrix every time you update a variable
    void SetCameraPosition(glm::vec3 pos)
    {
        cameraPosition = pos;
        updateMatrix();
    }
    // .. same for Front and Up

    // no need to use this-> all the time
    virtual void Draw()
    {
        this->shader.Use();
        this->shader.SetMatrix4("view", viewMatrix);    
    }
};

我的着色器代码:

Shader &Use(){ glUseProgram(this->ID); return *this; }

void SetMatrix4(const GLchar *name, const glm::mat4 &matrix, GLboolean useShader = false)
    { if (useShader)this->Use(); glUniformMatrix4fv(glGetUniformLocation(this->ID, name), 1, GL_FALSE, glm::value_ptr(matrix)); }

我的游戏代码:

Camera *View;

projection2 = glm::perspective(glm::radians(44.0f), (float)this->Width / (float)this->Width, 0.1f, 100.0f);

AssetController::LoadShader("../src/Shaders/Light.vert", "../src/Shaders/Light.frag", "light");

AssetController::GetShader("light").SetMatrix4("projection", projection2);

View = new Camera(AssetController::GetShader("light"));

(...)

GLfloat velocity = playerSpeed * deltaTime;
glm::vec3 camPosition;

// Update Players Position
if (movingLeft)
{
    if (Player->Position.x >= 0)
    {
        Player->Position.x -= velocity;
        if (Ball->Stuck)
            Ball->Position.x -= velocity;

        camPosition = View->GetCameraPosition();
        camPosition.x -= velocity / 2;
        View->SetCameraPosition(camPosition);
    }
}
else if (movingRight)
{
    if (Player->Position.x <= this->Width - Player->Size.x)
    {
        Player->Position.x += velocity;
        if (Ball->Stuck)
            Ball->Position.x += velocity;

        camPosition = View->GetCameraPosition();
        camPosition.x += velocity / 2;
        View->SetCameraPosition(camPosition);
    }
}

(...)

GameOver->Draw(*Renderer);
    View->Draw();

我的着色器: .vert:

#version 440 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0f);
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

.frag:

#version 440 core
out vec4 FragColor;

in vec2 TexCoord;

// texture samplers
uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    // linearly interpolate between both textures (80% container, 20% awesomeface)
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

【问题讨论】:

    标签: c++ opengl sdl glm-math


    【解决方案1】:

    问题是你只更新了局部位置变量cameraPosition,而不是视图矩阵,它在渲染过程中被传递给了OpenGL。

    将相机变量和矩阵公开也是一个坏习惯,因为它们可能会被错误地修改或不同步(就像你正在做的那样)。相反,您可以编写一对get/set 函数:

    class Camera
    {
    private:
       Shader shader;
    
       GLfloat     angle = -90.f;
    
       glm::vec3   cameraFront = glm::vec3(0.0f, 0.0f, -1.0f),
                   cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f),
                   cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
    
       glm::mat4   viewMatrix;
    
       // recompute the view matrix from the camera variables
       void updateMatrix()
       {
          viewMatrix = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp);
       }
    
       // default constructor
       void defaultNew()
       {
          cameraPosition = glm::vec3(0.0f, 0.0f,  0.1f);
          cameraFront    = glm::vec3(0.0f, 0.0f, -1.0f);
          cameraUp       = glm::vec3(0.0f, 1.0f,  0.0f);
          updateMatrix();
       }
    
    public:
       Camera() { 
          defaultNew();
       }
       Camera(Shader &shader) { 
          this->shader = shader;
          defaultNew();  
       }
    
       glm::mat4 GetViewMatrix() const
       {
          // if your view matrix is always up-to-date, just return it directly
          return viewMatrix;
       }
    
       // get functions
       glm::vec3 GetCameraPosition() const { return cameraPosition; }
       // .. same for Front and Up
    
       // set functions
       // call updateMatrix every time you update a variable
       void SetCameraPosition(glm::vec3 p)
       {
          cameraPosition = p;
          updateMatrix();
       }
       // .. same for Front and Up
    
       // no need to use this-> all the time
       virtual void Draw()
       {
          shader.Use();
          shader.SetMatrix4("view", viewMatrix);
       }
    };
    

    然后当您更新相机位置时,只需使用这些函数而不是暴露的变量:

    view->SetCameraPosition(view->GetCameraPosition() + velocity / 2.0f);
    

    这将确保绘制调用始终使用更新后的视图矩阵而不是初始视图矩阵(之前就是这种情况,也是您麻烦的根源)。

    【讨论】:

    • @ChrisRoss 你能展示你更新的代码吗?另外,如果你打电话给SetMatrix4beforeUse(),会有区别吗?
    • @ChrisRoss 只是好奇:如果你将一些不同的视图矩阵传递给你的着色器,会有什么影响吗?
    • 在这一点上,基于当前的代码示例,我认为我们无法为您提供太多帮助;你能用你的full代码添加一个存储库的链接吗? (请勿在此处发布代码本身)
    • 我有点想不通;只是试图让 SDL 工作,以便我可以运行代码并调试它(希望如此)
    • 不认为启用深度与这个问题有关,但对于实心多边形的 3D 渲染仍然是必要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多