c++ - 粒子和 OpenGL 的问题,没有绘制任何内容
问题描述
我正在学习 OpenGL,我正在尝试在我的应用程序中实现一些粒子。
为此,我学习了一些课程。
但是当我尝试渲染我的粒子时,什么也没有发生,它甚至没有进入着色器(我试图在其中放置一些无限循环,但什么也没发生)。我尝试了很多东西,也许有一些我不明白的东西..
我创建了一个 Particle 类,带有一个构造函数、一个更新和一个绘制方法,我遵循课程的每一步,并将其调整到我的课程中(课程在主循环中做所有事情)。
我的粒子类有一些私有成员:
private:
size_t maxSize_;
std::vector<float> quadData_;
unsigned int dataVbo_;
std::vector<float> posData_;
unsigned int posVbo_;
std::vector<float> colorData_;
unsigned int colorVbo_;
std::list<Particle> allParticles_;
这是初始化Particles
:
Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{
posData_.resize(maxSize_*4);
colorData_.resize(maxSize_*4);
glGenBuffers(1, &dataVbo_);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);
// The VBO containing the positions and sizes of the particles
glGenBuffers(1, &posVbo_);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
// The VBO containing the colors of the particles
glGenBuffers(1, &colorVbo_);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
}
和平局:
void Particles::draw(){
size_t count(posData_.size());
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW); // Buffer orphaning, a common way to improve streaming perf. See above link for details.
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// 2nd attribute buffer : positions of particles' centers
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// 3rd attribute buffer : particles' colors
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
glVertexAttribDivisor(2, 1); // color : one per quad -> 1
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
在我的主循环中,我正在这样做:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
myParticules.update(elapsedTime);
glDisable(GL_DEPTH_TEST);
glUseProgram(_particleShad);
myParticles.draw();
我还发送了一些统一的 vec 和 mat,但没有什么重要的。
在我的着色器中,我只尝试这样做:
Vertex :
gl_Position = vec4(squareVertices.xyz, 1);
//squareVertices contain the vertices of my square for my particles
Fragment :
color = vec4(1, 1, 1, 1);
我没有发现任何问题,我真的需要一些帮助,我完全迷路了。
解决方案
您必须创建一个 VAO(顶点数组对象):
class Particles {
private:
// add:
GLuint vao;
...
初始化:
Particles::Particles(size_t maxSize)
: maxSize_(maxSize), quadData_({-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f})
{
posData_.resize(maxSize_*4);
colorData_.resize(maxSize_*4);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &dataVbo_);
glBindBuffer(GL_ARRAY_BUFFER, dataVbo_);
glBufferData(GL_ARRAY_BUFFER, quadData_.size() * sizeof(float), quadData_.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// The VBO containing the positions and sizes of the particles
glGenBuffers(1, &posVbo_);
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// The VBO containing the colors of the particles
glGenBuffers(1, &colorVbo_);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
// Initialize with empty (NULL) buffer : it will be updated later, each frame.
glBufferData(GL_ARRAY_BUFFER, maxSize_ * 4 * sizeof(float), NULL, GL_STREAM_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glVertexAttribDivisor(0, 0); // particles vertices : always reuse the same 4 vertices -> 0
glVertexAttribDivisor(1, 1); // positions : one per quad (its center) -> 1
glVertexAttribDivisor(2, 1); // color : one per quad -> 1
}
绘图代码:
void Particles::draw(){
size_t count(posData_.size());
glBindBuffer(GL_ARRAY_BUFFER, posVbo_);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), posData_.data());
glBindBuffer(GL_ARRAY_BUFFER, colorVbo_);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float) * 4, colorData_.data());
glBindVertexArray(vao);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}
请注意,您无需在draw()
调用期间更新您的 VAO 状态,只需在初始化期间即可。
推荐阅读
- css - Bootstrap 4删除/隐藏类
- java - 如何在没有 JDK 的情况下使用 tools.jar 中的 JavaCompiler
- javascript - ASP.NET .addClass 错误框不出现
- html - 我可以使用 Tachyons 将 img 标签的高度放在其父级内吗?
- asp.net - 如何在 IIS 中启用 https?
- javascript - 在 Angular 中检查 HTML5 文件 API 支持?
- xml - Sitemap XML 有多少篇文章?
- c# - CRUD ASP.NET Core 的最佳实践设计 DTO?
- java - HTTP 状态 500 - 未找到 AbstractValueFactoryProvider 类
- php - 如何显示php数组