void BulletSpheresApp::update() { // update time // update bullet context updateTime(); mContext->setGravity( vec3( 0 ) ); mContext->update(); // add attractive force mat4 * matrices = (mat4*)mMatrices->map( GL_WRITE_ONLY ); for( auto &body : mRigidBodies ){ body.update( mTimeElapsed ); int index = body.getId(); if( index >=2 ){ // small orbs for( int i=0; i<2; i++ ){ vec3 pos = mRigidBodies[i].getPos(); float size = mRigidBodies[i].getSize(); float strength = mRigidBodies[i].getStrength(); body.attract( pos, size, strength ); } matrices[index-2] = body.getMatrix(); } else { // big orbs float size = mRigidBodies[index].getSize(); body.attract( vec3( 0 ), size, 1.0f ); } } mMatrices->unmap(); }
void TessellationSampleApp::createIcosahedron() { const int faces[] = { 2, 1, 0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 1, 5, 0, 11, 6, 7, 11, 7, 8, 11, 8, 9, 11, 9, 10, 11, 10, 6, 1, 2, 6, 2, 3, 7, 3, 4, 8, 4, 5, 9, 5, 1, 10, 2, 7, 6, 3, 8, 7, 4, 9, 8, 5, 10, 9, 1, 6, 10 }; const float verts[] = { 0.000f, 0.000f, 1.000f, 0.894f, 0.000f, 0.447f, 0.276f, 0.851f, 0.447f, -0.724f, 0.526f, 0.447f, -0.724f, -0.526f, 0.447f, 0.276f, -0.851f, 0.447f, 0.724f, 0.526f, -0.447f, -0.276f, 0.851f, -0.447f, -0.894f, 0.000f, -0.447f, -0.276f, -0.851f, -0.447f, 0.724f, -0.526f, -0.447f, 0.000f, 0.000f, -1.000f }; mIndexCount = sizeof(faces) / sizeof(faces[0]); vertexArrayObject->bind(); // Create the VBO for positions: GLsizei stride = 3 * sizeof(float); vertexBufferObject->bind(); vertexBufferObject->bufferData(sizeof(verts), verts, GL_STATIC_DRAW); gl::enableVertexAttribArray( (GLuint)mPositionIndex ); gl::vertexAttribPointer( (GLuint)mPositionIndex, 3, GL_FLOAT, GL_FALSE, stride, 0 ); // Create the VBO for indices: indexBufferObject->bind(); indexBufferObject->bufferData( sizeof(faces), faces, GL_STATIC_DRAW ); }
void TransformFeedbackIntroApp::runTransformFeedback() { gl::ScopedVao scopeVao( mVao ); gl::ScopedGlslProg scopeGlsl( mGlsl ); gl::ScopedState scopeState( GL_RASTERIZER_DISCARD, true ); // Bind the capture vbo to the TransformVertex binding point to capture the calculations gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, TransformIndex, mCaptureVbo ); // Begin Transform Feedback, using the primitive we plan to draw gl::beginTransformFeedback( GL_POINTS ); gl::drawArrays( GL_POINTS, 0, NumVertices ); // End Transform Feedback gl::endTransformFeedback(); glFlush(); // Fetch and print results GLfloat feedback[NumVertices]; mCaptureVbo->getBufferSubData( 0, sizeof(float) * NumVertices, feedback ); console() << feedback[0] << " " << feedback[1] << " " << feedback[2] << " " << feedback[3] << " " << feedback[4] << std::endl; }
void SinOrbitApp::reset(bool pShader) { mColor = vec4(randVec3(), randFloat(0.005f, 0.025f)); mAlpha = randFloat(0.01f, 0.1f); auto w = randFloat(5.0f,10.0f); auto maxR = randFloat(350.0f, 400.0f); auto numPtcls = randInt(500, 1000); mPtcls.clear(); for (int i = 0; i < numPtcls; ++i) { mPtcls.push_back( ptcl( randFloat(0.2f, 0.8f), randFloat(400.0f-w, 400.0f+w), randFloat(0.01f, 0.05f), randFloat(-0.5f, 0.5f), randFloat(1.0f, 3.0f) ) ); } if (pShader) { mPointShader = gl::GlslProg::create(loadAsset("points.vert"), loadAsset("points.frag")); geom::BufferLayout attribs; attribs.append(geom::POSITION, 2, sizeof(ptcl), offsetof(ptcl, Pos), 0); mPointData = gl::Vbo::create(GL_ARRAY_BUFFER, mPtcls, GL_DYNAMIC_DRAW); mPointMesh = gl::VboMesh::create(mPtcls.size(), GL_POINTS, { {attribs, mPointData} }); } else { mPointData->bufferData(mPtcls.size()*sizeof(ptcl), mPtcls.data(), GL_DYNAMIC_DRAW); } }
void PointCloudVAO::updateCloud() { mDS->update(); auto depth = mDS->getDepthFrame(); auto iter = depth->getIter(); mPoints.clear(); while (iter.line()) { while (iter.pixel()) { if (iter.x() % mParamStep == 0 && iter.y() % mParamStep == 0) { float x = (float)iter.x(); float y = (float)iter.y(); float z = (float)iter.v(); if (z > mParamDepthMin && z < mParamDepthMax) { auto world = mDS->getDepthSpacePoint(vec3(x, y, z)); auto diffuse = mDS->getColorFromDepthSpace(world); mPoints.push_back(Pt(world, diffuse)); } } } } mVbo->bufferData(mPoints.size()*sizeof(Pt), mPoints.data(), GL_DYNAMIC_DRAW); }
void PointCloudApp::update() { mCinderRS->update(); mPoints.clear(); Channel16u cChanDepth = mCinderRS->getDepthFrame(); mTexRgb->update(mCinderRS->getRgbFrame()); for (int dy = 0; dy < mDepthDims.y; ++dy) { for (int dx = 0; dx < mDepthDims.x; ++dx) { float cDepth = (float)*cChanDepth.getData(dx, dy); if (cDepth > 100 && cDepth < 1000) { vec3 cPos = mCinderRS->getDepthSpacePoint(vec3(dx, dy, cDepth)); vec2 cUV = mCinderRS->getColorCoordsFromDepthImage(static_cast<float>(dx), static_cast<float>(dy), cDepth); mPoints.push_back(CloudPoint(cPos, cUV)); } } } mBufferObj->bufferData(mPoints.size()*sizeof(CloudPoint), mPoints.data(), GL_DYNAMIC_DRAW); mMeshObj = gl::VboMesh::create(mPoints.size(), GL_POINTS, { { mAttribObj, mBufferObj } }); mDrawObj->replaceVboMesh(mMeshObj); }
void InstancedTeapotsApp::update() { // move the camera up and down on Y mCam.lookAt( vec3( 0, CAMERA_Y_RANGE.first + abs(sin( getElapsedSeconds() / 4)) * (CAMERA_Y_RANGE.second - CAMERA_Y_RANGE.first), 0 ), vec3( 0 ) ); // update our instance positions; map our instance data VBO, write new positions, unmap vec3 *positions = (vec3*)mInstanceDataVbo->mapWriteOnly( true ); for( size_t potX = 0; potX < NUM_INSTANCES_X; ++potX ) { for( size_t potY = 0; potY < NUM_INSTANCES_Y; ++potY ) { float instanceX = potX / (float)NUM_INSTANCES_X - 0.5f; float instanceY = potY / (float)NUM_INSTANCES_Y - 0.5f; // just some nonsense math to move the teapots in a wave vec3 newPos( instanceX * vec3( DRAW_SCALE, 0, 0 ) + instanceY * vec3( 0, 0, DRAW_SCALE ) + vec3( 0, 30, 0 ) * sinf( getElapsedSeconds() * 3 + instanceX * 3 + instanceY * 3 ) ); *positions++ = newPos; } } mInstanceDataVbo->unmap(); }
void SinOrbitApp::update() { if (mStarted) { if (getElapsedFrames() % 300 == 0) { reset(false); } for (auto &p : mPtcls) { p.step(); } mPointData->bufferData(mPtcls.size()*sizeof(ptcl), mPtcls.data(), GL_DYNAMIC_DRAW); } }
void SpiderWebApp::reset() { mIterationIndex = 0; mPositionBufTexs[0].reset(); mPositionBufTexs[1].reset(); mPositionBufTexs[0] = nullptr; mPositionBufTexs[1] = nullptr; mVaos[0].reset(); mVaos[1].reset(); mVaos[0] = nullptr; mVaos[1] = nullptr; // mPositions[0] = nullptr; // with these, we only get movement the first time around // mPositions[1] = nullptr; // mVelocities[0] = nullptr; // mVelocities[1] = nullptr; // mConnections[0] = nullptr; // mConnections[1] = nullptr; // mConnectionLen[0] = nullptr; // mConnectionLen[1] = nullptr; // mLineIndices = nullptr; // adding this gives us 3 rounds of movement mPositions[0]->mapReplace(); mPositions[1]->mapReplace(); mVelocities[0]->mapReplace(); mVelocities[1]->mapReplace(); mConnections[0]->mapReplace(); mConnections[1]->mapReplace(); mConnectionLen[0]->mapReplace(); mConnectionLen[1]->mapReplace(); mLineIndices->mapReplace(); // RESET and generate web mWeb->reset(); mWeb = nullptr; generateWeb(); setupBuffers(); }
void RandomSpawn::updateParticles() { mCinderDS->update(); mChanDepth = mCinderDS->getDepthFrame(); //Channel16u::Iter cIter = mChanDepth.getIter(); for (int sp = 0; sp < S_SPAWN_COUNT; ++sp) { if (mPointsParticles.size() < S_MAX_COUNT) { int cX = randInt(0, mDepthDims.x); int cY = randInt(0, mDepthDims.y); float cZ = (float)mChanDepth.getValue(ivec2(cX, cY)); if (cZ > S_MIN_Z&&cZ < S_MAX_Z) { vec3 cWorld = mCinderDS->getDepthSpacePoint(static_cast<float>(mDepthDims.x-cX), static_cast<float>(cY), static_cast<float>(cZ)); // pos, acc size life vec3 cAcc(randFloat(-5.f, 5.f), randFloat(0.5f, 3.5f), randFloat(-5.f, 5.f)); float cSize = randFloat(S_POINT_SIZE*0.25f, S_POINT_SIZE); int cLife = randInt(60, 120); ColorA cColor = ColorA(randFloat(), 0.1f, randFloat(), 1.0f); mPointsParticles.push_back(CloudParticle(cWorld, cSize, cLife, cColor)); } } } //now update particles for (auto pit = mPointsParticles.begin(); pit != mPointsParticles.end();) { if (pit->PAge == 0) pit = mPointsParticles.erase(pit); else { pit->step(mPerlin); ++pit; } } mDataInstance_P->bufferData(mPointsParticles.size()*sizeof(CloudParticle), mPointsParticles.data(), GL_DYNAMIC_DRAW); }
void Choreo3DApp::update() { setFrameRate(frameRate); //DISABLE CAMERA INTERACTION IF MOUSE IS OVER UI REGION if (getMousePos().x > 3 * getWindowWidth()/4. && camActive) { camActive = false; mCamUi.disconnect(); mCamUi.disable(); cout << "disabling camera UI" << endl; } else { if (!camActive) { mCamUi.connect(getWindow()); mCamUi.enable(); } camActive = true; cout << "enabling camera UI" << endl; } mGlsl->uniform("uColor", markerColour ); if (!paused) { //UPDATE POSITIONS //MAP INSTANCE DATA TO VBO //WRITE NEW POSITIONS //UNMAP glm::vec3 *newPositions = (glm::vec3*)mInstanceDataVbo->mapReplace(); for( int i = 0; i < jointList.size(); ++i ) { float instanceX = jointList[i].jointPositions[FRAME_COUNT].x; float instanceY = jointList[i].jointPositions[FRAME_COUNT].y; float instanceZ = jointList[i].jointPositions[FRAME_COUNT].z; vec3 newPos(vec3(instanceX,instanceY, instanceZ)); //CREATE A NEW VEC3 FOR UPDATING THE VBO framePositions[i] = newPos; } //REPLACE VEC3s IN VBO BY INCREMENTING THE POINTER for (int i = 0; i < framePositions.size(); i++){ *newPositions++ = framePositions[i]; } handTrail.update(framePositions[26], dancerColor); // std::cout << framePositions[17] << std::endl; skeleton.update(framePositions); mInstanceDataVbo->unmap(); // std::cout << "position: " << positions[0] << std::endl; if (ribbonsActive)updateRibbons(); //MANUALLY INCREMENT THE FRAME, IF THE FRAME_COUNT EXCEEDS TOTAL FRAMES, RESET THE COUNTER if (FRAME_COUNT < TOTAL_FRAMES) { FRAME_COUNT += 1; } else { FRAME_COUNT = 0; } //std::cout << getAverageFps() << std:: endl; // std::cout << "frame rate: " << getAverageFps() << ", frame count: " << FRAME_COUNT << std::endl; //define changed color // Color temp = Color(dancerColor[0],dancerColor[1],dancerColor[2]); mCurrentFrame++; //MANUALLY ADVANCE THE CURRENT FRAME - WITH RESPECT TO THE DANCERS } updateGui(); }
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 TransformFeedbackClothSimulationApp::loadBuffers() { int n = 0; array<vec4, POINTS_TOTAL> positions; array<vec3, POINTS_TOTAL> velocities; array<ivec4, POINTS_TOTAL> connections; // We set all connections to -1, because these will only be updated // if there are connection indices. Explanation below. connections.fill( ivec4( -1 ) ); for( int j = 0; j < POINTS_Y; j++ ) { float fj = (float)j / (float)POINTS_Y; for( int i = 0; i < POINTS_X; i++ ) { float fi = (float)i / (float)POINTS_X; // This fills the position buffer data, basically makes a grid positions[n] = vec4((fi - 0.5f) * (float)POINTS_X, // x coordinate (fj - 0.5f) * (float)POINTS_Y, // y coordinate 0.6f * sinf(fi) * cosf(fj), // z coordinate 1.0f); // homogenous coordinate or w // This allows us to figure out the indices of the four points // surrounding the current point. This will be used to index // into the texture buffer. if( j != (POINTS_Y - 1) ) { // if it's not one of the top row, don't move if( i != 0 ) connections[n][0] = n - 1; if( j != 0 ) connections[n][1] = n - POINTS_X; if( i != (POINTS_X - 1) ) connections[n][2] = n + 1; if( j != (POINTS_Y - 1) ) connections[n][3] = n + POINTS_X; } n++; } } // Create the Position Buffer with the intial position data mPositions[0] = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec4), positions.data(), GL_STATIC_DRAW ); // Create another Position Buffer that is null, for ping-ponging mPositions[1] = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec4), nullptr, GL_STATIC_DRAW ); // Create the Velocity Buffer with the intial velocity data mVelocities[0] = gl::Vbo::create( GL_ARRAY_BUFFER, velocities.size() * sizeof(vec3), velocities.data(), GL_STATIC_DRAW ); // Create another Velocity Buffer that is null, for ping-ponging mVelocities[1] = gl::Vbo::create( GL_ARRAY_BUFFER, velocities.size() * sizeof(vec3), nullptr, GL_STATIC_DRAW ); // Create Connection Buffer to index into the Texture Buffer mConnections = gl::Vbo::create( GL_ARRAY_BUFFER, connections.size() * sizeof(ivec4), connections.data(), GL_STATIC_DRAW ); for( int i = 0; i < 2; i++ ) { // Initialize the Vao's holding the info for each buffer mVaos[i] = gl::Vao::create(); // Bind the vao to capture index data for the glsl mVaos[i]->bind(); mPositions[i]->bind(); gl::vertexAttribPointer( POSITION_INDEX, 4, GL_FLOAT, GL_FALSE, 0, NULL ); gl::enableVertexAttribArray( POSITION_INDEX ); mVelocities[i]->bind(); gl::vertexAttribPointer( VELOCITY_INDEX, 3, GL_FLOAT, GL_FALSE, 0, NULL ); gl::enableVertexAttribArray( VELOCITY_INDEX ); mConnections->bind(); gl::vertexAttribIPointer( CONNECTION_INDEX, 4, GL_INT, 0, NULL ); gl::enableVertexAttribArray( CONNECTION_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. mFeedbackObjs[i] = gl::TransformFeedbackObj::create(); // Bind the TransformFeedbackObj and bind each corresponding buffer // to it's index. mFeedbackObjs[i]->bind(); gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, POSITION_INDEX, mPositions[i] ); gl::bindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, VELOCITY_INDEX, mVelocities[i] ); mFeedbackObjs[i]->unbind(); // Create Texture buffers to gain access to the lookup tables for // calculations in the update shader mPosBufferTextures[i] = gl::BufferTexture::create( mPositions[i], GL_RGBA32F ); } // Create an element buffer to draw the lines (connections) between the points array<uint32_t, CONNECTIONS_TOTAL*2> lineIndices; uint32_t * e = lineIndices.data(); for( int j = 0; j < POINTS_Y; j++ ) { for( int i = 0; i < POINTS_X - 1; i++ ) { *e++ = i + j * POINTS_X; *e++ = 1 + i + j * POINTS_Y; } } for( int i = 0; i < POINTS_X; i++ ) { for( int j = 0; j < POINTS_Y - 1; j++ ) { *e++ = i + j * POINTS_X; *e++ = POINTS_X + i + j * POINTS_X; } } mLineIndices = lineIndices.size(); mLineElementBuffer = gl::Vbo::create( GL_ELEMENT_ARRAY_BUFFER, lineIndices.size() * sizeof(uint32_t), lineIndices.data(), GL_STATIC_DRAW ); }