提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
OpenGL /GLES 使用Pyqt5 + glad
前言
提示:这里可以添加本文要记录的大概内容:
该文章主要介绍使用Pyqt5 创建一个窗口,通过C++ 中的glad来调用opengl或opengles(glad同样支持gles<移动端>,代码实现完全一样,不同的是着色器语言版本不一样),改文章主要通过动态链接库的方式进行。Pyqt5与C++的链接,目前在Linux平台与window均成功实现,两频台在导出动态库时存在差异!
提示:以下是本篇文章正文内容,下面案例可供参考
一、python和C++
动态连接库编写!参考以下文章 使用Ctypes读取动态链接库。
https://blog.csdn.net/CxzKkgg/article/details/123796292
二、glad 方法解析(直接复制代码不能运行 需要理解)
1.gladLoadGL()
根据上下文,获取一个更高的opengl版本
bool Simu::Initglad() {
int status;
try {
status = gladLoadGL();
std::cout << "status" << status <<std::endl;
} catch (int e) {
return false;
}
if (status == 0) {
return false;
}
return true; }
2.初始化VAO VBO
glBufferData 如果后期使用glBufferSubData 需提前设置数据总长度,数据设置未NULL。如下50000. glBufferSubData适合动态增加数据,只需要将未增加部分加入到GL_ARRAY_BUFFER。如果是glBufferData 只能是每次全部添加所有数据。
glBufferData(GL_ARRAY_BUFFER, 数据总字节长度,NULL, GL_STATIC_DRAW);
第三个参数在使用glBufferSubData 填写NULL ,为了设置一块内存供VBO使用.
bool Simu::InitVaoVbo()
{
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
// glBufferData(GL_ARRAY_BUFFER, sizeof(Vetor)*MSqu.size(), MSqu.data(), GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vetor)*50000,NULL, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vetor), (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vetor), (void*)(3* sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return true;
}
3.动态增加数据点时
绑定VBO —>复制顶点数据—>解绑
glBufferData 使用方法与初始化一致
glBufferSubData 使用方法如下所示
glBufferSubData(GL_ARRAY_BUFFER,currtpos, sizeof(Vetor), &MSqu.at(MSqu.size()-1));
currtpos :需要修改的数据起始字节位置
sizeof(Vetor) :修改等数据字节总长度
&MSqu.at(MSqu.size()-1):修改数据地址
void Simu::updataMsqu()
{
// 测试数据改变增加动态点
CVector3D point;
float x,y,xx,yy, r;
point = MSqu.back().vPos;
x = point.x();
y = point.y();
r = MSqu.back().vColor.z()+0.01f;
// std::cout << "color" << r << std::endl;
xx = x - 0.001f;
yy = y - 0.002f;
Vetor point2( xx,yy, 0.0f, 0.0f,0.0f,r);
MSqu.push_back(point2);
// 绑定VBO 绑定数据 解绑
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
// glBufferData(GL_ARRAY_BUFFER, sizeof(Vetor)*MSqu.size(), MSqu.data(), GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER,currtpos, sizeof(Vetor), &MSqu.at(MSqu.size()-1));
currtpos = sizeof(Vetor) * MSqu.size();
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
4.多对象绘制
1.(针对绘制顶点不同的,及不同的多个物体例如球和正方体)使用多个VAO 来区分在绘制时需要重新绑定VAO
重新绑定不同的VAO 进行绘制
glBindVertexArray(m_vao);
glLineWidth(2);
glDrawArrays(GL_LINE_STRIP, 0, CSimul->getCount());
2.(针对绘制顶点相同的,两个正方体但位置不同)
不需要重新绑定VAO 在绘制前左成变换矩阵
glBindVertexArray(VAO);
for (unsigned int i = 0; i < 10; i++)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
ourShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
3 glVertexAttribPointer
该方法使用时绑定VBO 与当前的 VBO关联!
在一个vao多个vbo时 绑定vbo 使用该方法!
总结
继续更新