| 144 | | |
| 145 | | |
| 146 | | return image; |
| | 151 | } |
| | 152 | |
| | 153 | /** create quad, line and point geometry data all with consistent particle positions.*/ |
| | 154 | void createGeometry(unsigned int numParticles, |
| | 155 | osg::Geometry* quad_geometry, |
| | 156 | osg::Geometry* line_geometry, |
| | 157 | osg::Geometry* point_geometry) |
| | 158 | { |
| | 159 | // particle corner offsets |
| | 160 | osg::Vec2 offset00(0.0f,0.0f); |
| | 161 | osg::Vec2 offset10(1.0f,0.0f); |
| | 162 | osg::Vec2 offset01(0.0f,1.0f); |
| | 163 | osg::Vec2 offset11(1.0f,1.0f); |
| | 164 | |
| | 165 | osg::Vec2 offset0(0.5f,0.0f); |
| | 166 | osg::Vec2 offset1(0.5f,1.0f); |
| | 167 | |
| | 168 | osg::Vec2 offset(0.5f,0.5f); |
| | 169 | |
| | 170 | |
| | 171 | // configure quad_geometry; |
| | 172 | osg::Vec3Array* quad_vertices = 0; |
| | 173 | osg::Vec2Array* quad_offsets = 0; |
| | 174 | if (quad_geometry) |
| | 175 | { |
| | 176 | quad_vertices = new osg::Vec3Array(numParticles*4); |
| | 177 | quad_offsets = new osg::Vec2Array(numParticles*4); |
| | 178 | |
| | 179 | quad_geometry->setVertexArray(quad_vertices); |
| | 180 | quad_geometry->setTexCoordArray(0, quad_offsets); |
| | 181 | quad_geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, numParticles*4)); |
| | 182 | } |
| | 183 | |
| | 184 | // configure line_geometry; |
| | 185 | osg::Vec3Array* line_vertices = 0; |
| | 186 | osg::Vec2Array* line_offsets = 0; |
| | 187 | if (line_geometry) |
| | 188 | { |
| | 189 | line_vertices = new osg::Vec3Array(numParticles*2); |
| | 190 | line_offsets = new osg::Vec2Array(numParticles*2); |
| | 191 | |
| | 192 | line_geometry->setVertexArray(line_vertices); |
| | 193 | line_geometry->setTexCoordArray(0, line_offsets); |
| | 194 | line_geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, numParticles*2)); |
| | 195 | } |
| | 196 | |
| | 197 | // configure point_geometry; |
| | 198 | osg::Vec3Array* point_vertices = 0; |
| | 199 | osg::Vec2Array* point_offsets = 0; |
| | 200 | if (point_geometry) |
| | 201 | { |
| | 202 | point_vertices = new osg::Vec3Array(numParticles); |
| | 203 | point_offsets = new osg::Vec2Array(numParticles); |
| | 204 | |
| | 205 | point_geometry->setVertexArray(point_vertices); |
| | 206 | point_geometry->setTexCoordArray(0, point_offsets); |
| | 207 | point_geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, numParticles)); |
| | 208 | } |
| | 209 | |
| | 210 | // set up vertex attribute data. |
| | 211 | for(unsigned int i=0; i< numParticles; ++i) |
| | 212 | { |
| | 213 | osg::Vec3 pos( random(0.0f, 1.0f), random(0.0f, 1.0f), random(0.0f, 1.0f)); |
| | 214 | |
| | 215 | // quad particles |
| | 216 | if (quad_vertices) |
| | 217 | { |
| | 218 | (*quad_vertices)[i*4] = pos; |
| | 219 | (*quad_vertices)[i*4+1] = pos; |
| | 220 | (*quad_vertices)[i*4+2] = pos; |
| | 221 | (*quad_vertices)[i*4+3] = pos; |
| | 222 | (*quad_offsets)[i*4] = offset00; |
| | 223 | (*quad_offsets)[i*4+1] = offset01; |
| | 224 | (*quad_offsets)[i*4+2] = offset11; |
| | 225 | (*quad_offsets)[i*4+3] = offset10; |
| | 226 | } |
| | 227 | |
| | 228 | // line particles |
| | 229 | if (line_vertices) |
| | 230 | { |
| | 231 | (*line_vertices)[i*2] = pos; |
| | 232 | (*line_vertices)[i*2+1] = pos; |
| | 233 | (*line_offsets)[i*2] = offset0; |
| | 234 | (*line_offsets)[i*2+1] = offset1; |
| | 235 | } |
| | 236 | |
| | 237 | // point particles |
| | 238 | if (point_vertices) |
| | 239 | { |
| | 240 | (*point_vertices)[i] = pos; |
| | 241 | (*point_offsets)[i] = offset; |
| | 242 | } |
| | 243 | } |
| 154 | | osg::Geometry* geometry = new PrecipitationGeometry; |
| 155 | | geode->addDrawable(geometry); |
| 156 | | |
| 157 | | osg::StateSet* stateset = geometry->getOrCreateStateSet(); |
| 158 | | |
| 159 | | // set up geometry. |
| 160 | | { |
| 161 | | |
| 162 | | // per vertex properties |
| 163 | | osg::Vec3Array* vertices = new osg::Vec3Array(numParticles*4); |
| 164 | | osg::Vec3Array* offsets = new osg::Vec3Array(numParticles*4); |
| 165 | | |
| 166 | | osg::Vec3 frameDelta = velocity*(2.0f/60.0f); |
| 167 | | float size = 1.0; |
| 168 | | |
| 169 | | for(unsigned int i=0; i< numParticles; ++i) |
| 170 | | { |
| 171 | | (*vertices)[i*4].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); |
| 172 | | (*vertices)[i*4+1] = (*vertices)[i*4]; |
| 173 | | (*vertices)[i*4+2] = (*vertices)[i*4]; |
| 174 | | (*vertices)[i*4+3] = (*vertices)[i*4]; |
| 175 | | (*offsets)[i*4].z() = random(0.0, 1.0); |
| 176 | | (*offsets)[i*4+1].z() = (*offsets)[i*4].z(); |
| 177 | | (*offsets)[i*4+2].z() = (*offsets)[i*4].z(); |
| 178 | | (*offsets)[i*4+3].z() = (*offsets)[i*4].z(); |
| 179 | | (*offsets)[i*4].x() = 0.0; |
| 180 | | (*offsets)[i*4].y() = 0.0; |
| 181 | | (*offsets)[i*4+1].x() = 0.0; |
| 182 | | (*offsets)[i*4+1].y() = 1.0; |
| 183 | | (*offsets)[i*4+2].x() = 1.0; |
| 184 | | (*offsets)[i*4+2].y() = 1.0; |
| 185 | | (*offsets)[i*4+3].x() = 1.0; |
| 186 | | (*offsets)[i*4+3].y() = 0.0; |
| 187 | | } |
| 188 | | |
| 189 | | geometry->setVertexArray(vertices); |
| 190 | | geometry->setTexCoordArray(0, offsets); |
| 191 | | |
| 192 | | // overall attributes |
| 193 | | osg::Vec4Array* colours = new osg::Vec4Array(1); |
| 194 | | (*colours)[0].set(0.5f,0.5f,0.5f,1.0f); |
| 195 | | geometry->setColorArray(colours); |
| 196 | | geometry->setColorBinding(osg::Geometry::BIND_OVERALL); |
| 197 | | |
| 198 | | geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, numParticles*4)); |
| 199 | | } |
| | 251 | osg::Geometry* quad_geometry = 0; |
| | 252 | osg::Geometry* line_geometry = 0; |
| | 253 | osg::Geometry* point_geometry = 0; |
| | 254 | |
| | 255 | #if 1 |
| | 256 | quad_geometry = new PrecipitationGeometry; |
| | 257 | quad_geometry->setUseVertexBufferObjects(true); |
| | 258 | quad_geometry->setInitialBound(bb); |
| | 259 | geode->addDrawable(quad_geometry); |
| | 260 | |
| | 261 | osg::StateSet* quad_stateset = quad_geometry->getOrCreateStateSet(); |
| | 262 | { |
| | 263 | osg::Program* program = new osg::Program; |
| | 264 | quad_stateset->setAttribute(program); |
| | 265 | |
| | 266 | // get shaders from source |
| | 267 | program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("quad_rain.vert"))); |
| | 268 | program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("rain.frag"))); |
| | 269 | } |
| | 270 | #endif |
| | 271 | |
| | 272 | #if 0 |
| | 273 | line_geometry = new PrecipitationGeometry; |
| | 274 | line_geometry->setUseVertexBufferObjects(true); |
| | 275 | line_geometry->setInitialBound(bb); |
| | 276 | geode->addDrawable(line_geometry); |
| | 277 | |
| | 278 | osg::StateSet* line_stateset = line_geometry->getOrCreateStateSet(); |
| | 279 | { |
| | 280 | osg::Program* program = new osg::Program; |
| | 281 | line_stateset->setAttribute(program); |
| | 282 | |
| | 283 | // get shaders from source |
| | 284 | program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("line_rain.vert"))); |
| | 285 | program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("rain.frag"))); |
| | 286 | } |
| | 287 | #endif |
| | 288 | |
| | 289 | |
| | 290 | #if 0 |
| | 291 | point_geometry = new PrecipitationGeometry; |
| | 292 | point_geometry->setUseVertexBufferObjects(true); |
| | 293 | point_geometry->setInitialBound(bb); |
| | 294 | geode->addDrawable(point_geometry); |
| | 295 | |
| | 296 | osg::StateSet* point_stateset = point_geometry->getOrCreateStateSet(); |
| | 297 | { |
| | 298 | osg::Program* program = new osg::Program; |
| | 299 | point_stateset->setAttribute(program); |
| | 300 | |
| | 301 | // get shaders from source |
| | 302 | program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("point_rain.vert"))); |
| | 303 | program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("point_rain.frag"))); |
| | 304 | } |
| | 305 | #endif |
| | 306 | |
| | 307 | |
| | 308 | createGeometry(numParticles, quad_geometry, line_geometry, point_geometry); |
| | 309 | |