C++ 用于在slam中绘制特征点的opengl着色器

C++ 用于在slam中绘制特征点的opengl着色器,c++,opengl,glsl,glm-math,slam,C++,Opengl,Glsl,Glm Math,Slam,我想使用opengl着色器绘制点。 现在,我的代码使用glvertex3f(pos.x、pos.y、pos.z),但是当使用它绘制的点太多时,它会变慢。所以我想使用着色器和gldrawArray。但这不是工作。请检查我的密码 原始代码: for (const auto lm : landmarks) { const openvslam::Vec3_t pos_w = lm->get_pos_in_world(); glColor3ub(lm->color_[0],

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

原始代码:

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());
    }
片段着色器

#version 460

uniform mat4 mvpMat;


    in vec3 colorr;
    out vec4 frag_color;

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

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

uniform mat4 mvpMat;


    in vec3 colorr;
    out vec4 frag_color;

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

in vec3 colorr;
out vec4 frag_color;

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


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

使用以下数据结构表示点(或类似点):

struct TLandmarkData
{
glm::vec3位置;
glm::vec3颜色;
};
使用TLandmarks=std::vector;
创建顶点数组对象和顶点缓冲区对象(初始化时一次):
(另见)

tland标记地标;
GLuint vbo;
GLuint vao_;
glGenBuffers(1,&vbo);
glBindBuffer(GL_数组_BUFFER,vbo_);
glBufferData(GL_数组_缓冲区,landmarks.size()*sizeof(*landmarks.data()),landmarks.data(),GL_静态_绘图);
glGenVertexArrays(1和vao);
glBindVertexArray(vao_);
glvertexattributepointer(0,3,GL_FLOAT,GL_FALSE,sizeof(TLandmarkData),0);
GlenableVertexAttributeArray(0);
glvertexattributepointer(1,3,GL_FLOAT,GL_FALSE,sizeof(TLandmarkData),(void*)(sizeof(glm::vec3));
GlenableVertexAttributeArray(1);
glBindVertexArray(0);
glBindBuffer(GL_数组_BUFFER,0);
正如您所看到的,您不需要任何循环。如果数据发生更改,则可以更新缓冲区(
vbo

如果要绘制点,则绑定顶点阵列对象就足够了。count参数必须是顶点数:

glBindVertexArray(vao_);
gldrawArray(GL_点,0,landmarks.size());

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

#版本460
均匀mat4 mvpMat;
vec3测试位置的布局(位置=0);
vec3测试颜色中的布局(位置=1);
布局(位置=0)均匀mat4 worldtransform;
out-vec3-colorr;
真空总管(真空){
colorr=测试颜色;
gl_位置=worldtransform*vec4(测试_位置,1.0);
}
安装程序后,通过以下方式设置统一(每帧更新):

glm::mat4 toworld(1.0f);
//走向世界
// [...]
glUseProgram(myProgram);
glUniformMatrix4fv(0,1,GL_假,glm::value_ptr(toworld));

谢谢您的回答。在我的算法中,landmark(大小和位置)是非常快速地更改和更新新数据的,所以我使用for循环。如何实时更新和绘制点?@2255jj您可以更新缓冲区并在每个帧中指定vao。(在这种情况下,不需要矩阵变换)。生成
std::vector动态,并使用我答案的代码。注意:如果点数没有改变,则按(每帧)改变
vbo_u
的内容就足够了。更新代码,但它表示分割错误。有什么问题吗?请检查。@2255jj您错过了
glBindVertexArray(vao_u2;)
gldrawArray
之前。如果
vao_
vbo_
只是临时的,那么您必须通过
glDeleteBuffers(1,&vbo_)删除它们
gldeleteVertexarray(1,&vao)谢谢,它可以工作,但有一些问题。它画了一个不知名的大红场,波因斯的颜色全是白色。。还有一个问题,我可以在同一个窗口中同时使用GLDrawArray和glbegin()~glvertex()~glend()吗?
#version 460

in vec3 colorr;
out vec4 frag_color;

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