C++ 用于在slam中绘制特征点的opengl着色器
我想使用opengl着色器绘制点。 现在,我的代码使用glvertex3f(pos.x、pos.y、pos.z),但是当使用它绘制的点太多时,它会变慢。所以我想使用着色器和gldrawArray。但这不是工作。请检查我的密码 原始代码: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],
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);
}