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 | |