void ofxBvh::draw() { ofPushStyle(); ofFill(); for (int i = 0; i < joints.size(); i++) { ofxBvhJoint *o = joints[i]; glPushMatrix(); glMultMatrixf(o->getGlobalMatrix().getPtr()); if (o->isSite()) { ofSetColor(ofColor::yellow); billboard(); ofCircle(0, 0, 2); } else if (o->getChildren().size() == 1) { ofSetColor(ofColor::white); billboard(); ofCircle(0, 0, 2); } else if (o->getChildren().size() > 1) { if (o->isRoot()) ofSetColor(ofColor::cyan); else ofSetColor(ofColor::green); billboard(); ofCircle(0, 0, 2); } glPopMatrix(); if (o->getChildren().size() > 0) { glPushMatrix(); glMultMatrixf(o->getGlobalMatrix().getPtr()); glLineWidth(2); for (int i=0; i<o->getChildren().size(); ++i) { ofSetColor(ofColor::gray); ofVec3f v = o->getChildren()[i]->getOffset(); ofLine(0, 0, 0, v.x, v.y, v.z); } glPopMatrix(); } } ofPopStyle(); }
void Billboard::Update(Shader* a_Shader,glm::mat4 a_Cam){ // create billboard transform glm::vec3 zAxis = glm::normalize( a_Cam[3].xyz - position);//FORWARD glm::vec3 xAxis = glm::cross( glm::vec3(a_Cam[1].xyz), zAxis );//RIGHT glm::vec3 yAxis = glm::cross( zAxis, xAxis );//UP glm::mat4 billboard(glm::vec4(xAxis,0),glm::vec4(yAxis,0),glm::vec4(zAxis,0),glm::vec4(position,1)); a_Shader->SetUniform("Model","m4fv",1,false,glm::value_ptr(billboard)); }
void ofxBvh::draw() { ofPushStyle(); ofFill(); for (int i = 0; i < joints.size(); i++) { ofxBvhJoint *o = joints[i]; glPushMatrix(); glMultMatrixf(o->getGlobalMatrix().getPtr()); if (o->isSite()) { ofSetColor(ofColor::yellow); billboard(); ofDrawCircle(0, 0, 6); } else if (o->getChildren().size() == 1) { ofSetColor(ofColor::white); billboard(); ofDrawCircle(0, 0, 2); } else if (o->getChildren().size() > 1) { if (o->isRoot()) ofSetColor(ofColor::cyan); else ofSetColor(ofColor::green); billboard(); ofDrawCircle(0, 0, 4); } glPopMatrix(); } ofPopStyle(); }
void ParticleEmitter::Update(float a_deltaTime, const glm::mat4& a_cameraTransform) { // spawn particles m_emitTimer += a_deltaTime; while (m_emitTimer > m_emitRate) { Emit(); m_emitTimer -= m_emitRate; } auto iter = m_aliveParticles.begin(); unsigned int quad = 0; while (iter != m_aliveParticles.end()) { Particle * particle = (*iter); particle->lifetime += a_deltaTime; if (particle->lifetime >= particle->lifespan) { m_deadParticles.push_back(particle); iter = m_aliveParticles.erase(iter); // The element AFTER the one that got erased. } else { particle->pos += particle->vel * a_deltaTime; particle->size = glm::mix(m_startSize, m_endSize, particle->lifetime / particle->lifespan); particle->color = glm::mix(m_startColor, m_endColor, particle->lifetime / particle->lifespan); float halfSize = particle->size * 0.5f; m_vertexData[quad * 4 + 0].pos = glm::vec4(halfSize, halfSize, 0, 1); m_vertexData[quad * 4 + 0].color = particle->color; m_vertexData[quad * 4 + 1].pos = glm::vec4(-halfSize, halfSize, 0, 1); m_vertexData[quad * 4 + 1].color = particle->color; m_vertexData[quad * 4 + 2].pos = glm::vec4(-halfSize, -halfSize, 0, 1); m_vertexData[quad * 4 + 2].color = particle->color; m_vertexData[quad * 4 + 3].pos = glm::vec4(halfSize, -halfSize, 0, 1); m_vertexData[quad * 4 + 3].color = particle->color; //f*****g billboarding glm::vec3 zAxis = glm::normalize(a_cameraTransform[3].xyz - particle->pos); glm::vec3 xAxis = glm::cross(glm::vec3(a_cameraTransform[1].xyz), zAxis); glm::vec3 yAxis = glm::cross(zAxis, xAxis); glm::mat3 billboard(xAxis, yAxis, zAxis); //F*****G MMATTTTHHHHH m_vertexData[quad * 4 + 0].pos.xyz = billboard * m_vertexData[quad * 4 + 0].pos.xyz + particle->pos; m_vertexData[quad * 4 + 1].pos.xyz = billboard * m_vertexData[quad * 4 + 1].pos.xyz + particle->pos; m_vertexData[quad * 4 + 2].pos.xyz = billboard * m_vertexData[quad * 4 + 2].pos.xyz + particle->pos; m_vertexData[quad * 4 + 3].pos.xyz = billboard * m_vertexData[quad * 4 + 3].pos.xyz + particle->pos; ++quad; ++iter; } } }
void ParticleEmitter::update(float a_deltaTime, const glm::mat4& a_cameraTransform) { // spawn particles m_emitTimer += a_deltaTime; while (m_emitTimer > m_emitRate) { emit(); m_emitTimer -= m_emitRate; } auto iter = m_aliveParticles.begin(); unsigned int quad = 0; // update particles and turn live particles into billboarded quads while (iter != m_aliveParticles.end()) { Particle* particle = (*iter); particle->lifetime += a_deltaTime; if (particle->lifetime >= particle->lifespan) { // return to dead pool m_deadParticles.push_back(particle); iter = m_aliveParticles.erase(iter); } else { // move particle particle->position += particle->velocity * a_deltaTime; // size particle particle->size = glm::mix( m_startSize, m_endSize, particle->lifetime / particle->lifespan ); //rotate particle particle->rotation += m_rotatestep * a_deltaTime; // colour particle particle->colour = glm::mix( m_startColour, m_endColour, particle->lifetime / particle->lifespan ); // make a quad the correct size and colour float halfSize = particle->size * 0.5f; m_vertexData[quad * 4 + 0].position = glm::vec4( halfSize, halfSize, 0, 1 ); m_vertexData[quad * 4 + 0].colour = particle->colour; m_vertexData[quad * 4 + 0].texCoord = glm::vec2(0,0); m_vertexData[quad * 4 + 1].position = glm::vec4( -halfSize, halfSize, 0, 1 ); m_vertexData[quad * 4 + 1].colour = particle->colour; m_vertexData[quad * 4 + 1].texCoord = glm::vec2(1,0); m_vertexData[quad * 4 + 2].position = glm::vec4( -halfSize, -halfSize, 0, 1 ); m_vertexData[quad * 4 + 2].colour = particle->colour; m_vertexData[quad * 4 + 2].texCoord = glm::vec2(1,1); m_vertexData[quad * 4 + 3].position = glm::vec4( halfSize, -halfSize, 0, 1 ); m_vertexData[quad * 4 + 3].colour = particle->colour; m_vertexData[quad * 4 + 3].texCoord = glm::vec2(0,1); // create billboard transform glm::vec3 zAxis = glm::normalize( a_cameraTransform[3].xyz - particle->position );//FORWARD glm::vec3 xAxis = glm::cross( glm::vec3(a_cameraTransform[1].xyz), zAxis );//RIGHT glm::vec3 yAxis = glm::cross( zAxis, xAxis );//UP glm::mat3 billboard(xAxis,yAxis,zAxis); for (int i = 0; i < 4;++i){ m_vertexData[quad * 4 + i].position.xyz = billboard * glm::rotate(m_vertexData[quad * 4 + i].position,particle->rotation,glm::vec3(0,0,1)).xyz + particle->position; } ++quad; ++iter; } } }
void APP_SpotRotate::generatePlane() { //Vertex* aoVertices = new Vertex(); glm::vec4 tl = glm::vec4(-5, 5, 0, 1); glm::vec4 tr = glm::vec4(5, 5, 0, 1); glm::vec4 bl = glm::vec4(5, -5, 0, 1); glm::vec4 br = glm::vec4(-5, -5, 0, 1); //build rotation matrix float rot = m_time; glm::mat4 rotation = glm::rotate( rot, glm::vec3(0, 0, 1)); // create billboard transform vec3 zAxis = glm::normalize(vec3(GameCam->GetWorldTransform()[3]) - vec3(0, 0, 0)); //vec3 is the quad pos, left in for reference vec3 xAxis = glm::cross(vec3(GameCam->GetWorldTransform()[1]), zAxis); vec3 yAxis = glm::cross(zAxis, xAxis); glm::mat4 billboard(vec4(xAxis, 0), vec4(yAxis, 0), vec4(zAxis, 0), vec4(0, 0, 0, 1)); rotation = billboard * rotation; glm::mat4 position; //resulting vert position glm::mat4 trans; //top left vert trans = glm::translate(vec3(tl.xyz)); position = rotation * trans; tl = glm::vec4(position[3]); //top right vert trans = glm::translate(vec3(tr.xyz)); position = rotation * trans; tr = glm::vec4(position[3]); //bottom left vert trans = glm::translate(vec3(bl.xyz)); position = rotation * trans; bl = glm::vec4(position[3]); //bottom right vert trans = glm::translate(vec3(br.xyz)); position = rotation * trans; br = glm::vec4(position[3]); //generate buffers and mesh information float vertexData[] = { tl.x, tl.y, tl.z, 1, 0, 1, tr.x, tr.y, tr.z, 1, 1, 1, bl.x, bl.y, bl.z, 1, 1, 0, br.x, br.y, br.z, 1, 0, 0, }; unsigned int indexData[] = { 0, 1, 2, 0, 2, 3, }; glUseProgram(m_programID); //select the program to use //bind buffers glBindVertexArray(m_VAO); //bind vertex array object glBindBuffer(GL_ARRAY_BUFFER, m_VBO); //vertex buffer objet glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO); //index buffer object //enable arrays for incoming data glEnableVertexAttribArray(0); //enable vertex positions in the vertex shader glEnableVertexAttribArray(1); //enable texture coord in the vertex shader glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float)* 6, 0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)* 6, ((char*)0) + 16); glBufferData(GL_ARRAY_BUFFER, sizeof(float)* 6 * 4, vertexData, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)* 6, indexData, GL_STATIC_DRAW); unsigned int projectionViewUniform = glGetUniformLocation(m_programID, "ProjectionView"); //get the index of the ProjectionView uniform variable from the vertex shader glUniformMatrix4fv(projectionViewUniform, 1, false, glm::value_ptr(GameCam->GetProjectionView())); //set the Projection View uniform variabe in the vertex shader // unsigned int timeUniform = glGetUniformLocation(m_programID, "Time"); //get the Time uniform index from the vertex shader // glUniform1f(timeUniform, m_time); //set the Time uniform variabe in the vertex shader // // unsigned int heightUniform = glGetUniformLocation(m_programID, "HeightScale"); //get the Time uniform index from the vertex shader // float height = 1.0f; //TODO - do something more fun with the hieght value // glUniform1f(heightUniform, height); //set the Time uniform variabe in the vertex shader // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //enable wireframe render glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); //unbind and delte pointers glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }