void IntersectVisitor::apply(Billboard& node) { if (!enterNode(node)) return; // IntersectVisitor doesn't have getEyeLocal(), can we use NodeVisitor::getEyePoint()? const Vec3& eye_local = getEyePoint(); for(unsigned int i = 0; i < node.getNumDrawables(); i++ ) { const Vec3& pos = node.getPosition(i); osg::ref_ptr<RefMatrix> billboard_matrix = new RefMatrix; node.computeMatrix(*billboard_matrix,eye_local,pos); pushMatrix(billboard_matrix.get(), osg::Transform::RELATIVE_RF); intersect(*node.getDrawable(i)); popMatrix(); } leaveNode(); }
void ScreenMVCullVisitor::apply(Billboard& node) { bool status = _cullingStatus; bool firstStatus = _firstCullStatus; if(isCulled(node)) { _firstCullStatus = firstStatus; _cullingStatus = status; return; } // push the node's state. StateSet* node_state = node.getStateSet(); if(node_state) pushStateSet(node_state); // traverse any call callbacks and traverse any children. handle_cull_callbacks_and_traverse(node); const Vec3& eye_local = getEyeLocal(); const RefMatrix& modelview = *getModelViewMatrix(); for(unsigned int i = 0; i < node.getNumDrawables(); ++i) { const Vec3& pos = node.getPosition(i); Drawable* drawable = node.getDrawable(i); // need to modify isCulled to handle the billboard offset. // if (isCulled(drawable->getBound())) continue; if(drawable->getCullCallback()) { if(drawable->getCullCallback()->cull(this,drawable,&_renderInfo) == true) continue; } RefMatrix* billboard_matrix = createOrReuseMatrix(modelview); node.computeMatrix(*billboard_matrix,eye_local,pos); if(_computeNearFar && drawable->getBound().valid()) updateCalculatedNearFar(*billboard_matrix,*drawable,true); float depth = distance(pos,modelview); /* if (_computeNearFar) { if (d<_computed_znear) { if (d<0.0) OSG_NOTIFY(osg::WARN)<<"Alerting billboard handling ="<<d<< std::endl; _computed_znear = d; } if (d>_computed_zfar) _computed_zfar = d; } */ StateSet* stateset = drawable->getStateSet(); if(stateset) pushStateSet(stateset); if(osg::isNaN(depth)) { /*OSG_NOTIFY(osg::NOTICE)<<"CullVisitor::apply(Billboard&) detected NaN,"<<std::endl <<" depth="<<depth<<", pos=("<<pos<<"),"<<std::endl <<" *billboard_matrix="<<*billboard_matrix<<std::endl; OSG_NOTIFY(osg::DEBUG_INFO) << " NodePath:" << std::endl; for (NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i) { OSG_NOTIFY(osg::DEBUG_INFO) << " \"" << (*i)->getName() << "\"" << std::endl; }*/ } else { addDrawableAndDepth(drawable,billboard_matrix,depth); } if(stateset) popStateSet(); } // pop the node's state off the geostate stack. if(node_state) popStateSet(); _firstCullStatus = firstStatus; _cullingStatus = status; }
void Display() { DrawShadowMap(); /* Clear window; color specified in 'Initialize()' */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(ShaderProgram); /* Associate program with shader matrices */ GLint projectionUniform = glGetUniformLocation(ShaderProgram, "ProjectionMatrix"); if (projectionUniform == -1) { cerr << "Could not bind uniform ProjectionMatrix" << endl; exit(-1); } glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, ProjectionMatrix.matrix); GLint ViewUniform = glGetUniformLocation(ShaderProgram, "ViewMatrix"); if (ViewUniform == -1) { cerr << "Could not bind uniform ViewMatrix" << endl; exit(-1); } glUniformMatrix4fv(ViewUniform, 1, GL_FALSE, glm::value_ptr(camera.viewMatrix())); /* light */ GLint LightPos1Uniform = glGetUniformLocation(ShaderProgram, "lightPos1"); if (LightPos1Uniform == -1){ cerr << "Could not bind uniform lightPos1" << endl; exit(-1); } glUniform3fv(LightPos1Uniform, 1, glm::value_ptr(camera.viewMatrix() * glm::vec4(lights[0]->pos, 1.0))); GLint LightColor1Uniform = glGetUniformLocation(ShaderProgram, "lightColor1"); if (LightColor1Uniform == -1){ cerr << "Could not bind uniform lightColor1" << endl; exit(-1); } glUniform3fv(LightColor1Uniform, 1, glm::value_ptr(lights[0]->rgb)); /* green moving light */ GLint LightPos2Uniform = glGetUniformLocation(ShaderProgram, "lightPos2"); if (LightPos2Uniform == -1){ cerr << "Could not bind uniform lightPos2" << endl; exit(-1); } glUniform3fv(LightPos2Uniform, 1, glm::value_ptr(camera.viewMatrix() * glm::transpose(glm::make_mat4(ModelMatrix[6].matrix)) * glm::vec4(lights[1]->pos, 1))); GLint LightColor2Uniform = glGetUniformLocation(ShaderProgram, "lightColor2"); if (LightColor2Uniform == -1){ cerr << "Could not bind uniform lightColor2" << endl; exit(-1); } glUniform3fv(LightColor2Uniform, 1, glm::value_ptr(lights[1]->rgb)); GLint kA = glGetUniformLocation(ShaderProgram, "kA"); GLint kD = glGetUniformLocation(ShaderProgram, "kD"); GLint kS = glGetUniformLocation(ShaderProgram, "kS"); if (kA == -1 || kD == -1 || kS == -1) { cout << kA << kD << kS << endl; cerr << "Could not bind uniform light constants" << endl; exit(-1); } const glm::mat4 scale_bias_matrix = glm::mat4(glm::vec4(0.5f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.5f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 0.5f, 0.0f), glm::vec4(0.5f, 0.5f, 0.5f, 1.0f)); glUseProgram(ShaderProgram); glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "ShadowMatrix"), 1, GL_FALSE, glm::value_ptr(scale_bias_matrix * light_projection_matrix * light_view_matrix)); /* Get texture uniform handle from fragment shader */ GLuint ShadowUniform = glGetUniformLocation(ShaderProgram, "depth_texture"); /* Get texture uniform handle from fragment shader */ GLuint TextureUniform = glGetUniformLocation(ShaderProgram, "myTextureSampler"); glUniform1i(TextureUniform, 0); glUniform1i(ShadowUniform, 1); glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, depth_texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, crackles->TextureID); glEnableVertexAttribArray(vPosition); glEnableVertexAttribArray(vColor); glEnableVertexAttribArray(vNormal); glEnableVertexAttribArray(vUV); for (int i = 0; i < 7; i++) { glUniform1f(kA, objects[i]->kA * ky); glUniform1f(kD, objects[i]->kD * kx); glUniform1f(kS, objects[i]->kS * kc); glBindBuffer(GL_ARRAY_BUFFER, VBO[i]); glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, CBO[i]); glVertexAttribPointer(vColor, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, TCBO[i]); glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, NBO[i]); glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO[i]); GLint size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); GLint RotationUniform = glGetUniformLocation(ShaderProgram, "ModelMatrix"); if (RotationUniform == -1) { cerr << "Could not bind uniform ModelMatrix" << endl; exit(-1); } glUniformMatrix4fv(RotationUniform, 1, GL_TRUE, ModelMatrix[i].matrix); glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0); } for (int i = 0; i < 2; i++) { glUniform1f(kA, room_components[i]->kA * ky); glUniform1f(kD, room_components[i]->kD * kx); glUniform1f(kS, room_components[i]->kS * kc); glBindBuffer(GL_ARRAY_BUFFER, VBR[i]); glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, CBR[i]); glVertexAttribPointer(vColor, 3, GL_FLOAT,GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, NBR[i]); glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, TCBR[i]); glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBR[i]); GLint size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); GLint RoomUniform = glGetUniformLocation(ShaderProgram, "ModelMatrix"); if (RoomUniform == -1){ cerr << "Could not bind uniform ModelMatrix" << endl; exit(-1); } glUniformMatrix4fv(RoomUniform, 1, GL_FALSE, RoomMatrix[0].matrix); if (room_components[i]->texture != NULL && room_components[i]->texture->TextureID > 0) { /* Bind current texture */ glBindTexture(GL_TEXTURE_2D, room_components[i]->texture->TextureID); } /* Issue draw command, using indexed triangle list */ glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0); } /* Draw billboard */ glUniform1f(kA, billboard.kA * ky); glUniform1f(kD, billboard.kD * kx); glUniform1f(kS, billboard.kS * kc); glBindBuffer(GL_ARRAY_BUFFER, VBB); glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, CBB); glVertexAttribPointer(vColor, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, TCBB); glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, NBB); glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBB); GLint size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); GLint RotationUniform = glGetUniformLocation(ShaderProgram, "ModelMatrix"); if (RotationUniform == -1) { cerr << "Could not bind uniform ModelMatrix" << endl; exit(-1); } glUniformMatrix4fv(RotationUniform, 1, GL_FALSE, glm::value_ptr(billboard.getPosition())); glBindTexture(GL_TEXTURE_2D, billboard.texture->TextureID); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0); glDisable(GL_BLEND); /* Disable attributes */ glDisableVertexAttribArray(vPosition); glDisableVertexAttribArray(vColor); glDisableVertexAttribArray(vNormal); glDisableVertexAttribArray(vUV); /* Swap between front and back buffer */ glutSwapBuffers(); }