void Particle::update(const Perlin &perlin) { // get Perlin noise value based on my location and // elapsed seconds and turn this noise value into an angle. float nX = mLoc.x * 0.005f; float nY = mLoc.y * 0.005f; float nZ = app::getElapsedSeconds() * 0.1f; float noise = perlin.fBm( nX, nY, nZ ); float angle = noise * 15.0f; Vec2f noiseVector( cos( angle ), sin( angle ) ); mVel += noiseVector * 0.2f * ( 1.0f - mAgePercentage ); mLoc += mVel; mVel *= mDecay; if (mLoc.x > 0 && mLoc.x < getWindowWidth() ) { mXPercentage = (float) mLoc.x / (float) getWindowWidth(); } if (mLoc.y > 0 && mLoc.y < getWindowWidth() ) { mYPercentage = (float) mLoc.y / (float) getWindowHeight(); } if (mAge > mLifespan) { mIsDead = true; } else { mAge++; mAgePercentage = (float) mAge / (float) mLifespan; } }
void Particle::update( const Perlin &perlin, const Channel32f &channel, const Vec2i &mouseLoc ) { angle1 += M_PI/100; // get Perlin noise value based on my location and // elapsed seconds and turn this noise value into an angle. float nX = mLoc.x * 0.005f; float nY = mLoc.y * 0.005f; float nZ = app::getElapsedSeconds() * 0.1f; float noise = perlin.fBm( nX, nY, nZ ); float angle = noise * 15.0f; Vec2f noiseVector( cos( angle ), sin( angle ) ); mVel += noiseVector * 0.2f * ( 1.0f - mAgePer ); // mLoc.x = startLoc.x + 120*sin(angle1); // mLoc.y = startLoc.y + 120*cos(angle1); mLoc += mVel; mVel *= mDecay; mRadius = mScale * mAgePer; mAge++; if( mAge > mLifespan ) mIsDead = true; mAgePer = 1.0f - ( (float)mAge/(float)mLifespan ); }
void Particle::Step(float pElapsed, const Perlin &pNoise) { Age--; if (Age>0) { PAlpha = math<float>::min(1, ((float)Age * 0.5f * (float)Age) / (float)mLifeSpan); PPosition.y += mVelocity.y; float cNoise = pNoise.fBm(vec3(PPosition.x*0.005f, PPosition.y*0.01f, PPosition.z*0.005f)); float cAngle = cNoise*15.0f; PPosition.x += (cos(cAngle)*mVelocity.x*(1.0f-PAlpha))*0.1f; PPosition.z += (sin(cAngle)*mVelocity.z*(1.0f - PAlpha))*0.1f; mVelocity.x *= 1.001f; mVelocity.y *= .99999f; mVelocity.z *= 1.001f; float elapsedFrames = pElapsed; //PModelMatrix = mat4(); //PModelMatrix = glm::rotate(PModelMatrix, mRotSpeed *elapsedFrames* 0.2f, vec3(0, 0, 1)); //PModelMatrix = glm::rotate(PModelMatrix, mRotSpeed *elapsedFrames* 0.2f, vec3(1, 0, 0)); //PModelMatrix = glm::rotate(PModelMatrix, mRotSpeed *elapsedFrames* 0.2f, vec3(0, 1, 0)); //PModelMatrix = glm::translate(PModelMatrix, PPosition); } }
void svvimApp::update() { float noise = mPerlinGenerator.fBm(Vec2f(0., app::getElapsedSeconds())); app::console() << noise << "\n"; // Update alpha values getAlpha(); if (mPoolWaterMovie) mMaskTexture = mPoolWaterMovie.getTexture(); if (mCurrentMovie.isDone()) { incrementMovie(); } app::console() << 10 * app::getElapsedSeconds() << "\n"; mImageTexture = mCurrentMovie.getTexture(); //mImageTexture = mCurrentBgTexture; // ... }
void TerrainApp::addQuad( int x, int y ) { Vec2f p00( x, y ); Vec2f p10( x + 1, y ); Vec2f p11( x + 1, y + 1 ); Vec2f p01( x, y + 1 ); float zScale = mHeight; float noiseScale = mNoiseScale; float z00 = zScale * mPerlin.fBm( p00 * noiseScale ); float z10 = zScale * mPerlin.fBm( p10 * noiseScale ); float z11 = zScale * mPerlin.fBm( p11 * noiseScale ); float z01 = zScale * mPerlin.fBm( p01 * noiseScale ); size_t idx = mTriMesh.getNumVertices(); // positions Vec3f t00( p00.x - xSize / 2., z00, p00.y - ySize / 2. ); Vec3f t10( p10.x - xSize / 2., z10, p10.y - ySize / 2. ); Vec3f t11( p11.x - xSize / 2., z11, p11.y - ySize / 2. ); Vec3f t01( p01.x - xSize / 2., z01, p01.y - ySize / 2. ); mTriMesh.appendVertex( t00 ); mTriMesh.appendVertex( t10 ); mTriMesh.appendVertex( t01 ); mTriMesh.appendVertex( t10 ); mTriMesh.appendVertex( t11 ); mTriMesh.appendVertex( t01 ); // normals Vec3f n0 = ( t10 - t00 ).cross( t10 - t01 ).normalized(); Vec3f n1 = ( t11 - t10 ).cross( t11 - t01 ).normalized(); mTriMesh.appendNormal( n0 ); mTriMesh.appendNormal( n0 ); mTriMesh.appendNormal( n0 ); mTriMesh.appendNormal( n1 ); mTriMesh.appendNormal( n1 ); mTriMesh.appendNormal( n1 ); mTriMesh.appendTriangle( idx, idx + 1, idx + 2 ); mTriMesh.appendTriangle( idx + 3, idx + 4, idx + 5 ); }
void FurPoint::update(const Perlin &perlin, float stepX, float stepY, float stepZ){ if (1.0f - age / lifetime <= 0.0f) isDead = true; if (position.x < 0 || position.x > getWindowWidth()) isDead = true; if (position.y < 0 || position.y > getWindowHeight()) isDead = true; noiseFloat = perlin.fBm( position.x * stepX, position.y * stepY, getElapsedFrames() * stepZ ); noiseVec.x = cos(((noiseFloat) * M_PI_2) * 10.0f); noiseVec.y = sin(((noiseFloat) * M_PI_2) * 10.0f); velocity += noiseVec; velocity *= 0.5f; position += velocity; age++; }
void Water::createHeightMap(){ Perlin noise = Perlin(40); float channelSize = 400 ; cout << "Creating water height map - " << endl ; Channel heightMapChannel = Channel8u(channelSize, channelSize); Channel::Iter iter = heightMapChannel.getIter( heightMapChannel.getBounds()); float max_value = -1.0 ; float min_value = 10001.0 ; while(iter.line()){ while(iter.pixel()){ Vec2f current = iter.getPos(); float value = 255.0F * noise.fBm(5 * current.x/channelSize, 5 * current.y/channelSize); if( value > max_value){ max_value = value ; } if( value < min_value){ min_value = value ; } } } iter = heightMapChannel.getIter( heightMapChannel.getBounds()); while(iter.line()){ while(iter.pixel()){ Vec2f current = iter.getPos(); float value = 255.0f * noise.fBm(5 * current.x/channelSize, 5 * current.y/channelSize); value = 255.0f * (value - min_value) / (max_value - min_value); iter.v() = value ; } } heightMap = gl::Texture(heightMapChannel); cout << min_value << " " << max_value << endl ; cout << "Done creating water height map" << endl; }
void Particle::update(float delta, Perlin &perlin) { const float noise = perlin.fBm(mPosition * 0.005f + app::getElapsedSeconds() * Vec3f(0.1f, 0.1f, 0.1f)); const float angle = noise * 15.0f; mVelocity += 0.1f * Vec3f(cos(angle), sin(angle) - 0.3f, 2.0f * sin(angle) - 0.5f); mPosition += delta * mVelocity; mVelocity *= mVecolityDecay; mAge += 1; // flap if (mAge >= mLifespan) { mIsDead = true; } }
void DelayFeedback::addSplash( const Vec2f &pos ) { mSplashes.push_back( Splash() ); auto &splash = mSplashes.back(); splash.mCenter = pos; splash.mAlpha = 1; float radiusMin = ( 1 - (float)pos.y / (float)getWindowHeight() ) * MAX_RADIUS / 2; splash.mRadius = randFloat( radiusMin, 30 ); float endRadius = randFloat( MAX_RADIUS * 0.9f, MAX_RADIUS ); timeline().apply( &splash.mRadius, endRadius, 7, EaseOutExpo() ); timeline().apply( &splash.mAlpha, 0.0f, 7 ); float h = math<float>::min( 1, mPerlin.fBm( pos.normalized() ) * 7.0f ); splash.mColorHsv = Vec3f( fabsf( h ), 1, 1 ); }
void SpiderWebApp::setupBuffers() { // get all of the points from the spider web // buffer the positions std::array<vec4, MAX_POINTS> positions; std::array<vec3, MAX_POINTS> velocities; std::array<ivec4, MAX_POINTS> connections; std::array<vec4, MAX_POINTS> connectionLen; std::array<vec4, MAX_POINTS> colors; vector<ParticleRef> webPoints = mWeb->getPoints(); int n = 0; Perlin p = Perlin(); for( auto iter = webPoints.begin(); iter != webPoints.end(); ++iter ) { auto point = (*iter); vec2 pos = point->getPosition(); // create our initial positions positions[point->getId()] = vec4( pos.x, pos.y, 0.0, 1.0f ); // zero out velocities velocities[point->getId()] = vec3( 0.0f ); connections[n] = ivec4( -1 ); connectionLen[n] = vec4( 0.0 ); auto conn = point->getNeighbors(); // use first 4 connections of there are more int max = min(int(conn.size()), 4); for( int i = 0; i < max; ++i ){ auto connection = conn[i]; connections[n][i] = connection->getId(); // connectionLen[n][i] = distance( normalize(pos), normalize(connection->getPosition()) ); connectionLen[n][i] = distance( pos, connection->getPosition() ); } n++; // DEFINE alpha - helps make the line thickness look a bit varied float x = pos.x / getWindowWidth(); float y = pos.y / getWindowHeight(); float a = p.fBm( x, y ) * 2.0; a += 0.35; colors[point->getId()] = vec4( vec3( 1.0 ), a ); } for ( int i = 0; i < 2; i++ ) { mVaos[i] = gl::Vao::create(); gl::ScopedVao scopeVao( mVaos[i] ); { // buffer the positions mPositions[i] = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec4), positions.data(), GL_STATIC_DRAW ); { // bind and explain the vbo to your vao so that it knows how to distribute vertices to your shaders. gl::ScopedBuffer sccopeBuffer( mPositions[i] ); gl::vertexAttribPointer( POSITION_INDEX, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) 0 ); gl::enableVertexAttribArray( POSITION_INDEX ); } // buffer the velocities mVelocities[i] = gl::Vbo::create( GL_ARRAY_BUFFER, velocities.size() * sizeof(vec3), velocities.data(), GL_STATIC_DRAW ); { // bind and explain the vbo to your vao so that it knows how to distribute vertices to your shaders. gl::ScopedBuffer scopeBuffer( mVelocities[i] ); gl::vertexAttribPointer( VELOCITY_INDEX, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) 0 ); gl::enableVertexAttribArray( VELOCITY_INDEX ); } // buffer the connections mConnections[i] = gl::Vbo::create( GL_ARRAY_BUFFER, connections.size() * sizeof(ivec4), connections.data(), GL_STATIC_DRAW ); { // bind and explain the vbo to your vao so that it knows how to distribute vertices to your shaders. gl::ScopedBuffer scopeBuffer( mConnections[i] ); gl::vertexAttribIPointer( CONNECTION_INDEX, 4, GL_INT, 0, (const GLvoid*) 0 ); gl::enableVertexAttribArray( CONNECTION_INDEX ); } // buffer the connection lengths mConnectionLen[i] = gl::Vbo::create( GL_ARRAY_BUFFER, connectionLen.size() * sizeof(vec4), connectionLen.data(), GL_STATIC_DRAW ); { // bind and explain the vbo to your vao so that it knows how to distribute vertices to your shaders. gl::ScopedBuffer scopeBuffer( mConnectionLen[i] ); gl::vertexAttribPointer( CONNECTION_LEN_INDEX, 4, GL_FLOAT, GL_FLOAT, 0, (const GLvoid*) 0 ); gl::enableVertexAttribArray( CONNECTION_LEN_INDEX ); } // buffer the colors mColors[i] = gl::Vbo::create( GL_ARRAY_BUFFER, colors.size() * sizeof(vec4), colors.data(), GL_STATIC_DRAW ); { // bind and explain the vbo to your vao so that it knows how to distribute vertices to your shaders. gl::ScopedBuffer scopeBuffer( mColors[i] ); gl::vertexAttribPointer( COLOR_INDEX, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) 0 ); gl::enableVertexAttribArray( COLOR_INDEX ); } // Create a TransformFeedbackObj, which is similar to Vao // It's used to capture the output of a glsl and uses the // index of the feedback's varying variable names. mFeedbackObj[i] = gl::TransformFeedbackObj::create(); // Bind the TransformFeedbackObj and bind each corresponding buffer // to it's index. mFeedbackObj[i]->bind(); gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, POSITION_INDEX, mPositions[i] ); gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, VELOCITY_INDEX, mVelocities[i] ); mFeedbackObj[i]->unbind(); } } // create your two BufferTextures that correspond to your position buffers. mPositionBufTexs[0] = gl::BufferTexture::create( mPositions[0], GL_RGBA32F ); mPositionBufTexs[1] = gl::BufferTexture::create( mPositions[1], GL_RGBA32F ); auto strands = mWeb->getUniqueStrands(); int lines = strands.size(); mConnectionCount = lines; // create the indices to draw links between the cloth points mLineIndices = gl::Vbo::create( GL_ELEMENT_ARRAY_BUFFER, lines * 2 * sizeof(int), nullptr, GL_STATIC_DRAW ); auto e = (int *) mLineIndices->mapReplace(); for( auto iter = strands.begin(); iter != strands.end(); ++iter ){ auto strand = *iter; *e++ = strand.first->getId(); *e++ = strand.second->getId(); } mLineIndices->unmap(); }
void millionParticlesApp::setup() { gl::clear(); try { mPosShader = gl::GlslProg(ci::app::loadResource(POS_VS),ci::app::loadResource(POS_FS)); mVelShader = gl::GlslProg(ci::app::loadResource(VEL_VS),ci::app::loadResource(VEL_FS)); } catch( gl::GlslProgCompileExc &exc ) { std::cout << "Shader compile error: " << std::endl; std::cout << exc.what(); } catch( ... ) { std::cout << "Unable to load shader" << std::endl; } //controls mDrawTextures = false; mIsFullScreen = false; mFrameCounter = 0; mPerlin = Perlin(32,clock() * .1f); //initialize buffer Surface32f mPosSurface = Surface32f(PARTICLES,PARTICLES,true); Surface32f mVelSurface = Surface32f(PARTICLES,PARTICLES,true); Surface32f mInfoSurface = Surface32f(PARTICLES,PARTICLES,true); Surface32f mNoiseSurface = Surface32f(PARTICLES,PARTICLES,true); Surface32f::Iter iterator = mPosSurface.getIter(); while(iterator.line()) { while(iterator.pixel()) { mVertPos = Vec3f(Rand::randFloat(getWindowWidth()) / (float)getWindowWidth(), Rand::randFloat(getWindowHeight()) / (float)getWindowHeight(),0.0f); //velocity Vec2f vel = Vec2f(Rand::randFloat(-.005f,.005f),Rand::randFloat(-.005f,.005f)); float nX = iterator.x() * 0.005f; float nY = iterator.y() * 0.005f; float nZ = app::getElapsedSeconds() * 0.1f; Vec3f v( nX, nY, nZ ); float noise = mPerlin.fBm( v ); float angle = noise * 15.0f ; //vel = Vec3f( cos( angle ) * 6.28f, cos( angle ) * 6.28f, 0.0f ); //noise mNoiseSurface.setPixel(iterator.getPos(), Color( cos( angle ) * Rand::randFloat(.00005f,.0002f), sin( angle ) * Rand::randFloat(.00005f,.0002f), 0.0f )); //position + mass mPosSurface.setPixel(iterator.getPos(), ColorA(mVertPos.x,mVertPos.y,mVertPos.z, Rand::randFloat(.00005f,.0002f))); //forces + decay mVelSurface.setPixel(iterator.getPos(), Color(vel.x,vel.y, Rand::randFloat(.01f,1.00f))); //particle age mInfoSurface.setPixel(iterator.getPos(), ColorA(Rand::randFloat(.007f,1.0f), 1.0f,0.00f,1.00f)); } } //gl texture settings gl::Texture::Format tFormat; tFormat.setInternalFormat(GL_RGBA16F_ARB); gl::Texture::Format tFormatSmall; tFormat.setInternalFormat(GL_RGBA8); mSpriteTex = gl::Texture( loadImage( loadResource( "point.png" ) ), tFormatSmall); mNoiseTex = gl::Texture(mNoiseSurface, tFormatSmall); mNoiseTex.setWrap( GL_REPEAT, GL_REPEAT ); mNoiseTex.setMinFilter( GL_NEAREST ); mNoiseTex.setMagFilter( GL_NEAREST ); mPosTex = gl::Texture(mPosSurface, tFormat); mPosTex.setWrap( GL_REPEAT, GL_REPEAT ); mPosTex.setMinFilter( GL_NEAREST ); mPosTex.setMagFilter( GL_NEAREST ); mVelTex = gl::Texture(mVelSurface, tFormat); mVelTex.setWrap( GL_REPEAT, GL_REPEAT ); mVelTex.setMinFilter( GL_NEAREST ); mVelTex.setMagFilter( GL_NEAREST ); mInfoTex = gl::Texture(mInfoSurface, tFormatSmall); mInfoTex.setWrap( GL_REPEAT, GL_REPEAT ); mInfoTex.setMinFilter( GL_NEAREST ); mInfoTex.setMagFilter( GL_NEAREST ); //initialize fbo gl::Fbo::Format format; format.enableDepthBuffer(false); format.enableColorBuffer(true, 3); format.setMinFilter( GL_NEAREST ); format.setMagFilter( GL_NEAREST ); format.setWrap(GL_CLAMP,GL_CLAMP); format.setColorInternalFormat( GL_RGBA16F_ARB ); mFbo[0] = gl::Fbo(PARTICLES,PARTICLES, format); mFbo[1] = gl::Fbo(PARTICLES,PARTICLES, format); initFBO(); //fill dummy fbo vector<Vec2f> texCoords; vector<Vec3f> vertCoords, normCoords; vector<uint32_t> indices; gl::VboMesh::Layout layout; layout.setStaticIndices(); layout.setStaticPositions(); layout.setStaticTexCoords2d(); layout.setStaticNormals(); mVbo = gl::VboMesh(PARTICLES*PARTICLES,PARTICLES*PARTICLES,layout,GL_POINTS); for (int x = 0; x < PARTICLES; ++x) { for (int y = 0; y < PARTICLES; ++y) { indices.push_back( x * PARTICLES + y); texCoords.push_back( Vec2f( x/(float)PARTICLES, y/(float)PARTICLES)); } } mVbo.bufferIndices(indices); mVbo.bufferTexCoords2d(0, texCoords); }