【问题标题】:opengl shader for drawing feature point in slam [closed]用于在大满贯中绘制特征点的opengl着色器[关闭]
【发布时间】:2020-02-26 05:14:19
【问题描述】:

我想使用 opengl 着色器绘制点。 现在我的代码使用 glvertex3f(pos.x, pos.y, pos.z) 但是当使用它绘制的点太多时,它会变慢。所以我想使用着色器和 glDrawarrays。但它不起作用。请检查我的代码。

原代码:

for (const auto lm : landmarks) {
     const openvslam::Vec3_t pos_w = lm->get_pos_in_world();
     glColor3ub(lm->color_[0], lm->color_[1], lm->color_[2]);
     glVertex3f(pos_w.cast<float>().eval().x(),pos_w.cast<float>().eval().y(), pos_w.cast<float>().eval().z());
    }

我的代码:

for (const auto lm : landmarks) {

const openvslam::Vec3_t pos_w = lm->get_pos_in_world();
int buffer_size =  local_landmarks.size();

glGenBuffers(2, buffers_);

glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]);
glm::vec3 pos_pt = glm::vec3(pos_w.cast<float>().eval().x(),pos_w.cast<float>().eval().y(), pos_w.cast<float>().eval().z());
glBufferData(GL_ARRAY_BUFFER, 3*buffer_size*sizeof(float), &pos_pt , GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]);
glm::vec3 color_pt = glm::vec3(lm->color_[0], lm->color_[1], lm->color_[2]);
glBufferData(GL_ARRAY_BUFFER, buffer_size*3*sizeof(float), &color_pt, GL_DYNAMIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);

Eigen::Matrix4f mvp = s_cam_shader_opengl->GetProjectionModelViewMatrix();
//Eigen::Matrix4f mvp = s_cam_shader_opengl->GetProjectionMatrix() * s_cam_shader_opengl->GetModelViewMatrix();
glUniformMatrix4fv(mvp_location, 1, GL_FALSE, mvp.data());

glPointSize(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POINTS, 0, 3*num);

}

顶点着色器

#version 460

uniform mat4 mvpMat;

layout (location = 0) in vec3 test_position;
layout (location = 1) in vec3 test_color;

out vec3 colorr;

void main(void){
       colorr = test_color;
       gl_Position = vec4(test_position,1.0);
        }

片段着色器

#version 460

uniform mat4 mvpMat;


    in vec3 colorr;
    out vec4 frag_color;

    void main(void) {
        frag_color = vec4(colorr, 1.0);
    }

/////////////////////////////////////// //////////////////////

+编辑

我更新了代码,但它说分段错误。 有什么问题?

struct TLandmarkData
{
    glm::vec3 pos;
    glm::vec3 color;
};
using TLandmarks = std::vector<TLandmarkData>;

TLandmarks landmarks_;


...
code
...

glUseProgram(points_program_);


while(){

...

for (const auto lm : landmarks) {
TLandmarkData aaa;

glm::vec3 pos_pt = glm::vec3(pos_w.cast<float>().eval().x(),pos_w.cast<float>().eval().y(), pos_w.cast<float>().eval().z());
glm::vec3 color_pt = glm::vec3(lm->color_[0], lm->color_[1], lm->color_[2]);
aaa.pos = pos_pt;
aaa.color = color_pt;

landmarks_.push_back(aaa);
}

...

GLuint vbo_;
GLuint vao_;

glGenBuffers(1, &vbo_);
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
glBufferData(GL_ARRAY_BUFFER, landmarks_.size()*sizeof(*landmarks_.data()), landmarks_.data(), GL_STATIC_DRAW);

glGenVertexArrays(1, &vao_);
glBindVertexArray(vao_);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TLandmarkData), 0);
glEnableVertexAttribArray( 0 );
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TLandmarkData), (void*)(sizeof(glm::vec3)));
glEnableVertexAttribArray(1);

glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);


glDrawArrays(GL_POINTS, 0, landmarks_.size());


}

顶点着色器

#version 460

layout (location = 0) in vec3 test_position;
layout (location = 1) in vec3 test_color;

out vec3 colorr;

void main(void){
       colorr = test_color;
       gl_Position =   vec4(test_position,1.0);
        }

片段着色器

#version 460

in vec3 colorr;
out vec4 frag_color;

void main(void) {
    frag_color = vec4(colorr, 1.0);
}

+

【问题讨论】:

    标签: c++ opengl glsl glm-math slam


    【解决方案1】:

    您实际上要做的是创建landmarks.size() 缓冲区而不是1 个缓冲区。您必须创建一个缓冲区。为了获得最佳性能增益,您必须创建一次缓冲区(分别在仅更改时)并在着色器中进行世界变换。

    使用以下数据结构来表示一个点(或类似的aggregate):

    struct TLandmarkData
    {
        glm::vec3 pos;
        glm::vec3 color;
    };
    using TLandmarks = std::vector<TLandmarkData>;
    

    创建一个顶点数组对象和一个顶点缓冲区对象(在初始化时):
    (另见Vertex Specification

    TLandmarks landmarks;
    GLuint vbo_;
    GLuint vao_;
    
    glGenBuffers(1, &vbo_);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_);
    glBufferData(GL_ARRAY_BUFFER, landmarks.size()*sizeof(*landmarks.data()), landmarks.data(), GL_STATIC_DRAW);
    
    glGenVertexArrays(1, &vao_);
    glBindVertexArray(vao_);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TLandmarkData), 0);
    glEnableVertexAttribArray( 0 );
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TLandmarkData), (void*)(sizeof(glm::vec3)));
    glEnableVertexAttribArray(1);
    
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    

    如您所见,您不需要任何循环。如果数据发生变化,可以更新缓冲区(vbo_)(例如glBufferSubData)。

    当你想绘制点时,绑定顶点数组对象就足够了。 glDrawArrayscount 参数必须是顶点数:

    glBindVertexArray(vao_);
    glDrawArrays(GL_POINTS, 0, landmarks.size());
    

    使用mat4 类型的Uniform,将点转换为顶点着色器中的世界坐标:

    #version 460
    
    uniform mat4 mvpMat;
    
    layout (location = 0) in vec3 test_position;
    layout (location = 1) in vec3 test_color;
    
    layout (location=0) uniform mat4 worldtransform;
    
    out vec3 colorr;
    
    void main(void){
        colorr = test_color;
        gl_Position = worldtransform * vec4(test_position,1.0);
    }
    

    glUseProgram安装程序后,通过glUniformMatrix4fv设置统一(每帧更新):

    glm::mat4 toworld(1.0f);
    // set toworld
    // [...]
    
    glUseProgram(myProgram);
    glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(toworld));
    

    【讨论】:

    • 感谢您的回答。在我的算法中,地标(大小和位置)非常快速地更改和更新新数据,所以我使用 for 循环。如何实时更新和绘制点?
    • @2255jj 您也可以更新缓冲区并在每个帧中指定 vao。 (在这种情况下,您不需要矩阵转换)。动态生成std::vector&lt;TLandmarkData&gt;; 并使用我的答案代码。注意如果点数没有变化,将vbo_的内容更改为glBufferSubData(每帧)就足够了。
    • 更新代码但显示分段错误。什么问题?请检查。
    • @2255jj 你在glDrawArrays 之前错过了glBindVertexArray(vao_);。如果vao_vbo_ 只是临时的,那么你必须通过glDeleteBuffers(1, &amp;vbo_); 删除它们glDeleteVertexArrays(1, &amp;vao_);
    • 谢谢,它可以工作,但有些问题。它绘制了未知的大红色方块,并且点的颜色全是白色。还有一个问题,我可以在同一个窗口中将 glDrawarrays 与 glbegin()~ glvertex() ~ glend() 一起使用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    相关资源
    最近更新 更多