Particles, first pass

This commit is contained in:
Dmitri K 2016-12-06 01:32:38 -05:00
parent b1e7de08fb
commit 04c4c17b58
2 changed files with 153 additions and 80 deletions

View File

@ -32,6 +32,7 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <iostream> #include <iostream>
#include <ctime>
#include <stack> #include <stack>
#include <QMouseEvent> #include <QMouseEvent>
#include <typeinfo> #include <typeinfo>
@ -54,6 +55,8 @@ namespace
const int numVerticesSphere = numColSphere * numRowSphere + 2; const int numVerticesSphere = numColSphere * numRowSphere + 2;
const int numTriSphere = numColSphere*(numRowSphere-1)*2 + 2*numColSphere; const int numTriSphere = numColSphere*(numRowSphere-1)*2 + 2*numColSphere;
const GLuint particleLimit = 1024;
int m_lDirectionLocation; int m_lDirectionLocation;
int m_normalMatrixLoc; int m_normalMatrixLoc;
@ -241,18 +244,60 @@ void Viewer::draw()
modelStack.push(modelViewMatrix); modelStack.push(modelViewMatrix);
root.accept(*this); root.accept(*this);
drawTool(); drawParticles();
drawUi(); drawUi();
sunRotate.setToIdentity(); sunRotate.setToIdentity();
//float rotAngle = (frame * angle_mult) % 360; //float rotAngle = (frame * angle_mult) % 360;
} }
void Viewer::drawTool() {
objShader->bind();
// Get projection and camera transformations
QMatrix4x4 modelViewMatrix;
//camera()->getModelViewMatrix(modelViewMatrix);
QMatrix4x4 toolboxPos = QMatrix4x4();
float swingMult = 1;
//scale.translate(QVector3D(0,1.5,0));
toolboxPos.translate(0.6, -0.25, -1.6);
toolboxPos.rotate(-100, 0, 1, 0);
if(swing.active) {
swingMult = 0.5 + 0.5 * cos(fmin(swing.length, frame - swing.startFrame) * 2 * M_PI / swing.length);
if(frame - swing.startFrame > swing.length) {
swing.active = false;
}
}
toolboxPos.rotate(swingMult * -65, 0, 0, 1);
toolboxPos.scale(0.06);
objShader->setUniformValue(o_u_mvMatrix, modelViewMatrix * toolboxPos);
objShader->setUniformValue(o_u_nmMatrix, modelViewMatrix.normalMatrix());
// Draw the meshes
for (unsigned int i=0; i<_meshesGL.size(); ++i)
{
// Set its material properties
objShader->setUniformValue(o_u_kd, _meshesGL[i].diffuse);
objShader->setUniformValue(o_u_ks, _meshesGL[i].specular);
objShader->setUniformValue(o_u_kn, _meshesGL[i].specularExponent);
objShader->setUniformValue(o_u_ka, _meshesGL[i].alpha);
// Draw the mesh
glBindVertexArray(_meshesGL[i].vao);
glDrawArrays(GL_TRIANGLES, 0, _meshesGL[i].numVertices);
}
}
void Viewer::drawUi(){ void Viewer::drawUi(){
glClear(GL_DEPTH_BUFFER_BIT); // make ui always on top
drawTool();
m_program->bind(); m_program->bind();
glCullFace(GL_BACK); glCullFace(GL_BACK);
glClear(GL_DEPTH_BUFFER_BIT); // make ui always on top
QMatrix4x4 projectionMatrix; QMatrix4x4 projectionMatrix;
QMatrix4x4 uiViewMatrix; QMatrix4x4 uiViewMatrix;
@ -284,6 +329,35 @@ void Viewer::drawUi(){
} }
void Viewer::drawParticles(){
m_program->bind();
QMatrix4x4 projectionMatrix;
QMatrix4x4 modelViewMatrix;
camera()->getProjectionMatrix(projectionMatrix);
camera()->getModelViewMatrix(modelViewMatrix);
glBindVertexArray(m_VAOs[VAO_Particle]);
glBindBuffer(GL_ARRAY_BUFFER, VBO_Particle);
glBindBuffer(GL_ARRAY_BUFFER, VBO_Particle_Positions);
glBindBuffer(GL_ARRAY_BUFFER, VBO_Particle_Colors);
glActiveTexture(GL_TEXTURE0);
TexturePrograms[1]->bind();
m_program->setUniformValue(m_isSkyLoc, true);
m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix);
m_program->setUniformValue(m_normalMatrixLoc, modelViewMatrix.normalMatrix());
m_program->setUniformValue(m_colorLocation, QColor(255, 255, 255, 255));
m_program->setUniformValue(m_drawTextLoc, false);
m_program->setUniformValue(m_isLightLoc, true);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, particleLimit);
}
void Viewer::mouseMoveEvent(QMouseEvent* e) { void Viewer::mouseMoveEvent(QMouseEvent* e) {
//cout << "Viewer::mouseMoveEvent(QMouseEvent* e)" << endl; //cout << "Viewer::mouseMoveEvent(QMouseEvent* e)" << endl;
// Normal QGLViewer behavior. // Normal QGLViewer behavior.
@ -835,32 +909,8 @@ void Viewer::initGeometries()
glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetUV)); glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetUV));
glEnableVertexAttribArray(s_vUvLocation); glEnableVertexAttribArray(s_vUvLocation);
/*GLsizeiptr offsetVertices = 0;
GLsizeiptr offsetNormals = sizeof(verticesCube);
GLsizeiptr offsetUV = offsetNormals + sizeof(normals);
GLsizeiptr dataSize = offsetUV + sizeof(uvs);
glBindVertexArray(m_VAOs[VAO_Cube]);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]);
glBufferData(GL_ARRAY_BUFFER, dataSize, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, offsetVertices, sizeof(verticesCube), verticesCube);
glBufferSubData(GL_ARRAY_BUFFER, offsetNormals, sizeof(normals), normals);
glBufferSubData(GL_ARRAY_BUFFER, offsetUV, sizeof(uvs), uvs);
glVertexAttribPointer(m_vPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(m_vPositionLocation);
glVertexAttribPointer(m_vNormalLocation, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(sizeof(offsetNormals)));
glEnableVertexAttribArray(m_vNormalLocation);
glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(offsetUV)));
glEnableVertexAttribArray(s_vUvLocation);//*/
// Fill Sphere VBO // Fill Sphere VBO
GLsizeiptr offsetSphereV = 0; GLsizeiptr offsetSphereV = 0;
GLsizeiptr offsetSphereN = offsetSphereV + sizeof(sphereVertices); GLsizeiptr offsetSphereN = offsetSphereV + sizeof(sphereVertices);
GLsizeiptr sphereDataSize = offsetSphereN + sizeof(sphereNormals); GLsizeiptr sphereDataSize = offsetSphereN + sizeof(sphereNormals);
@ -882,6 +932,69 @@ void Viewer::initGeometries()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[EBO_Sphere]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[EBO_Sphere]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphereIndices), sphereIndices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphereIndices), sphereIndices, GL_STATIC_DRAW);
// Fill Particle VBO
//==============================================================
// CODE RÉFÉRENCÉ
// http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/
//==============================================================
GLfloat verticesParticle[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
};
GLfloat particlePositions[particleLimit][4] = {}; // x, y, z and time, for shader's lifetime calculation
GLubyte particleColors[particleLimit][4] = {};
srand((unsigned int) time(NULL));
for(int i = 0; i < particleLimit; i++){
double r = rand() / (RAND_MAX);
double g = rand() / (RAND_MAX);
double b = rand() / (RAND_MAX);
particlePositions[i][0] = r*10;
particlePositions[i][1] = g*10;
particlePositions[i][2] = b*10;
particlePositions[i][3] = 0;
particleColors[i][0] = r;
particleColors[i][1] = g;
particleColors[i][2] = b;
particleColors[i][3] = 1;
}
glBindVertexArray(m_VAOs[VAO_Particle]);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Particle]);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesParticle), verticesParticle, GL_STATIC_DRAW);
// particle position buffer
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Particle_Positions]);
glBufferData(GL_ARRAY_BUFFER, sizeof(particlePositions), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(particlePositions), particlePositions);
// particle color buffer
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Particle_Colors]);
glBufferData(GL_ARRAY_BUFFER, sizeof(particleColors), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(particleColors), particleColors);
glVertexAttribPointer(m_vPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(m_vPositionLocation);
glVertexAttribPointer(m_vNormalLocation, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(offsetNormals));
glEnableVertexAttribArray(m_vNormalLocation);
glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetUV));
glEnableVertexAttribArray(s_vUvLocation);//*/
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
//==============================================================
// FIN DE CODE RÉFÉRENCÉ
//==============================================================
} }
void Viewer::initBuffers(){ void Viewer::initBuffers(){
@ -893,46 +1006,6 @@ void Viewer::initBuffers(){
} }
void Viewer::drawTool() {
objShader->bind();
// Get projection and camera transformations
QMatrix4x4 modelViewMatrix;
//camera()->getModelViewMatrix(modelViewMatrix);
QMatrix4x4 toolboxPos = QMatrix4x4();
float swingMult = 1;
//scale.translate(QVector3D(0,1.5,0));
toolboxPos.translate(0.6, -0.25, -1.6);
toolboxPos.rotate(-100, 0, 1, 0);
if(swing.active) {
swingMult = 0.5 + 0.5 * cos(fmin(swing.length, frame - swing.startFrame) * 2 * M_PI / swing.length);
if(frame - swing.startFrame > swing.length) {
swing.active = false;
}
}
toolboxPos.rotate(swingMult * -65, 0, 0, 1);
toolboxPos.scale(0.06);
objShader->setUniformValue(o_u_mvMatrix, modelViewMatrix * toolboxPos);
objShader->setUniformValue(o_u_nmMatrix, modelViewMatrix.normalMatrix());
// Draw the meshes
for (unsigned int i=0; i<_meshesGL.size(); ++i)
{
// Set its material properties
objShader->setUniformValue(o_u_kd, _meshesGL[i].diffuse);
objShader->setUniformValue(o_u_ks, _meshesGL[i].specular);
objShader->setUniformValue(o_u_kn, _meshesGL[i].specularExponent);
objShader->setUniformValue(o_u_ka, _meshesGL[i].alpha);
// Draw the mesh
glBindVertexArray(_meshesGL[i].vao);
glDrawArrays(GL_TRIANGLES, 0, _meshesGL[i].numVertices);
}
}
void Viewer::visit(Cube &s) void Viewer::visit(Cube &s)
{ {
m_program->bind(); m_program->bind();
@ -1026,7 +1099,6 @@ void Viewer::visit(SceneGroup &s)
modelStack.pop(); modelStack.pop();
} }
void Viewer::setPhong(bool on) { void Viewer::setPhong(bool on) {
m_program->bind(); m_program->bind();
m_program->setUniformValue(m_isPhongLoc, on); m_program->setUniformValue(m_isPhongLoc, on);

View File

@ -89,6 +89,7 @@ signals:
protected : protected :
virtual void draw(); virtual void draw();
virtual void drawParticles();
virtual void drawSkybox(); virtual void drawSkybox();
virtual void drawTool(); virtual void drawTool();
virtual void init(); virtual void init();
@ -184,8 +185,8 @@ private:
QColor* activeColor; QColor* activeColor;
int activeShape; int activeShape;
enum VAO_IDs { VAO_Cube, VAO_Sphere, NumVAOs }; enum VAO_IDs { VAO_Cube, VAO_Sphere, VAO_Particle, NumVAOs };
enum Buffer_IDs { VBO_Cube, VBO_Sphere, EBO_Sphere, NumBuffers }; enum Buffer_IDs { VBO_Cube, VBO_Sphere, EBO_Sphere, VBO_Particle, VBO_Particle_Positions, VBO_Particle_Colors, NumBuffers };
enum RenderBuffer_IDs { RenderBuffer_Main, NumRenderBuffers }; enum RenderBuffer_IDs { RenderBuffer_Main, NumRenderBuffers };
GLuint m_VAOs[NumVAOs]; GLuint m_VAOs[NumVAOs];