int main() { /* Procedura startowa: - Inicjalizacja biblioteki Allegro 5 - Inicjalizacja dodatków dla Allegro 5 - Rejestracja zdarzeñ Allegro 5 - Uruchomienie g³ównej pêtli - Zamkniêcie biblioteki Allegro 5 - Koniec programu */ ALLEGRO_DISPLAY *display = NULL; ALLEGRO_EVENT_QUEUE *event_queue = NULL; Init initializer; if(!initializer.initAllegro(display, event_queue, resolutionWidth, resolutionHeight)) { return 1; // coœ posz³o nie tak, wychodzimy... } if(!initializer.initAddons()) { return 1; // coœ posz³o nie tak, wychodzimy... } initializer.registerEvents(display, event_queue); gameLoop(); initializer.closeAllegro(display, event_queue); return 0; }
int main(int argc, char **argv) { Init init; Game game(init.getWindow(), init.getGamepad()); while(state != QUIT) { if(state == PLAY) { game.update(); game.draw(); } else if(state == PAUSE) { game.update(); } else if(state == GAME_OVER) { game.update(); } else if(state == RESTART) { game.restart(); } } init.quit(); return 0; }
TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) { Record *Operator = Dag->getNodeType(); if (Operator->isSubClassOf("ValueType")) { // If the operator is a ValueType, then this must be "type cast" of a leaf // node. if (Dag->getNumArgs() != 1) error("Type cast only valid for a leaf node!"); Init *Arg = Dag->getArg(0); TreePatternNode *New; if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) { New = new TreePatternNode(DI); // If it's a regclass or something else known, set the type. New->setType(getIntrinsicType(DI->getDef())); } else if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) { New = ParseTreePattern(DI); } else { Arg->dump(); error("Unknown leaf value for tree pattern!"); return 0; } // Apply the type cast... New->updateNodeType(getValueType(Operator), TheRecord->getName()); return New; } if (!ISE.getNodeTypes().count(Operator)) error("Unrecognized node '" + Operator->getName() + "'!"); std::vector<std::pair<TreePatternNode*, std::string> > Children; for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { Init *Arg = Dag->getArg(i); if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) { Children.push_back(std::make_pair(ParseTreePattern(DI), Dag->getArgName(i))); } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) { Record *R = DefI->getDef(); // Direct reference to a leaf DagNode? Turn it into a DagNode if its own. if (R->isSubClassOf("DagNode")) { Dag->setArg(i, new DagInit(R, std::vector<std::pair<Init*, std::string> >())); --i; // Revisit this node... } else { Children.push_back(std::make_pair(new TreePatternNode(DefI), Dag->getArgName(i))); // If it's a regclass or something else known, set the type. Children.back().first->setType(getIntrinsicType(R)); } } else { Arg->dump(); error("Unknown leaf value for tree pattern!"); } } return new TreePatternNode(Operator, Children); }
Record *MapTableEmitter::getInstrForColumn(Record *KeyInstr, ListInit *CurValueCol) { ListInit *RowFields = InstrMapDesc.getRowFields(); std::vector<Init*> KeyValue; // Construct KeyValue using KeyInstr's values for RowFields. for (Init *RowField : RowFields->getValues()) { Init *KeyInstrVal = KeyInstr->getValue(RowField)->getValue(); KeyValue.push_back(KeyInstrVal); } // Get all the instructions that share the same KeyValue as the KeyInstr // in RowInstrMap. We search through these instructions to find a match // for the current column, i.e., the instruction which has the same values // as CurValueCol for all the fields in ColFields. const std::vector<Record*> &RelatedInstrVec = RowInstrMap[KeyValue]; ListInit *ColFields = InstrMapDesc.getColFields(); Record *MatchInstr = nullptr; for (unsigned i = 0, e = RelatedInstrVec.size(); i < e; i++) { bool MatchFound = true; Record *CurInstr = RelatedInstrVec[i]; for (unsigned j = 0, endCF = ColFields->size(); (j < endCF) && MatchFound; j++) { Init *ColFieldJ = ColFields->getElement(j); Init *CurInstrInit = CurInstr->getValue(ColFieldJ)->getValue(); std::string CurInstrVal = CurInstrInit->getAsUnquotedString(); Init *ColFieldJVallue = CurValueCol->getElement(j); MatchFound = (CurInstrVal == ColFieldJVallue->getAsUnquotedString()); } if (MatchFound) { if (MatchInstr) { // Already had a match // Error if multiple matches are found for a column. std::string KeyValueStr; for (Init *Value : KeyValue) { if (!KeyValueStr.empty()) KeyValueStr += ", "; KeyValueStr += Value->getAsString(); } PrintFatalError("Multiple matches found for `" + KeyInstr->getName() + "', for the relation `" + InstrMapDesc.getName() + "', row fields [" + KeyValueStr + "], column `" + CurValueCol->getAsString() + "'"); } MatchInstr = CurInstr; } } return MatchInstr; }
string dtype(Record* rec) { Init* typeInit = rec->getValueInit("VT"); if(!typeInit) return ""; string type = typeInit->getAsString(); if(type == "iPTR") return "void*"; string vec = ""; if(type[0] == 'v') { size_t i = 1; while(i != type.size() && type[i] <= '9' && type[i] >= '0') i++; vec = type.substr(1, i - 1); type = type.substr(i); } if(vec.size() > 0 && type.size() > 0) { int typeSize, vecElements; if( sscanf(vec.c_str(), "%d", &vecElements) == 1 && sscanf(type.c_str() + 1, "%d", &typeSize) == 1 && typeSize * vecElements > 256) { return ""; } } if(type == "i8") return "byte" + vec; else if(type == "i16") return "short" + vec; else if(type == "i32") return "int" + vec; else if(type == "i64") return "long" + vec; else if(type == "f32") return "float" + vec; else if(type == "f64") return "double" + vec; else return ""; }
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Init i; switch(int pid = fork()) { case -1: std::cout << "Error attempting to fork to background. Exiting" << std::endl; return -1; break; case 0: setsid(); i.run(); break; default: std::cout << argv[0] << " Running in background ("<< pid << ")" << std::endl; fclose(stdout); fclose(stdin); fclose(stderr); break; } return a.exec(); }
json::Value JSONEmitter::translateInit(const Init &I) { // Init subclasses that we return as JSON primitive values of one // kind or another. if (isa<UnsetInit>(&I)) { return nullptr; } else if (auto *Bit = dyn_cast<BitInit>(&I)) { return Bit->getValue() ? 1 : 0; } else if (auto *Bits = dyn_cast<BitsInit>(&I)) { json::Array array; for (unsigned i = 0, limit = Bits->getNumBits(); i < limit; i++) array.push_back(translateInit(*Bits->getBit(i))); return std::move(array); } else if (auto *Int = dyn_cast<IntInit>(&I)) { return Int->getValue(); } else if (auto *Str = dyn_cast<StringInit>(&I)) { return Str->getValue(); } else if (auto *Code = dyn_cast<CodeInit>(&I)) { return Code->getValue(); } else if (auto *List = dyn_cast<ListInit>(&I)) { json::Array array; for (auto val : *List) array.push_back(translateInit(*val)); return std::move(array); } // Init subclasses that we return as JSON objects containing a // 'kind' discriminator. For these, we also provide the same // translation back into TableGen input syntax that -print-records // would give. json::Object obj; obj["printable"] = I.getAsString(); if (auto *Def = dyn_cast<DefInit>(&I)) { obj["kind"] = "def"; obj["def"] = Def->getDef()->getName(); return std::move(obj); } else if (auto *Var = dyn_cast<VarInit>(&I)) { obj["kind"] = "var"; obj["var"] = Var->getName(); return std::move(obj); } else if (auto *VarBit = dyn_cast<VarBitInit>(&I)) { if (auto *Var = dyn_cast<VarInit>(VarBit->getBitVar())) { obj["kind"] = "varbit"; obj["var"] = Var->getName(); obj["index"] = VarBit->getBitNum(); return std::move(obj); } } else if (auto *Dag = dyn_cast<DagInit>(&I)) { obj["kind"] = "dag"; obj["operator"] = translateInit(*Dag->getOperator()); if (auto name = Dag->getName()) obj["name"] = name->getAsUnquotedString(); json::Array args; for (unsigned i = 0, limit = Dag->getNumArgs(); i < limit; ++i) { json::Array arg; arg.push_back(translateInit(*Dag->getArg(i))); if (auto argname = Dag->getArgName(i)) arg.push_back(argname->getAsUnquotedString()); else arg.push_back(nullptr); args.push_back(std::move(arg)); } obj["args"] = std::move(args); return std::move(obj); } // Final fallback: anything that gets past here is simply given a // kind field of 'complex', and the only other field is the standard // 'printable' representation. assert(!I.isConcrete()); obj["kind"] = "complex"; return std::move(obj); }
/// ParseValue - Parse a tblgen value. This returns null on error. /// /// Value ::= SimpleValue ValueSuffix* /// ValueSuffix ::= '{' BitList '}' /// ValueSuffix ::= '[' BitList ']' /// ValueSuffix ::= '.' ID /// Init *TGParser::ParseValue(Record *CurRec) { Init *Result = ParseSimpleValue(CurRec); if (Result == 0) return 0; // Parse the suffixes now if present. while (1) { switch (Lex.getCode()) { default: return Result; case tgtok::l_brace: { TGLoc CurlyLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' std::vector<unsigned> Ranges = ParseRangeList(); if (Ranges.empty()) return 0; // Reverse the bitlist. std::reverse(Ranges.begin(), Ranges.end()); Result = Result->convertInitializerBitRange(Ranges); if (Result == 0) { Error(CurlyLoc, "Invalid bit range for value"); return 0; } // Eat the '}'. if (Lex.getCode() != tgtok::r_brace) { TokError("expected '}' at end of bit range list"); return 0; } Lex.Lex(); break; } case tgtok::l_square: { TGLoc SquareLoc = Lex.getLoc(); Lex.Lex(); // eat the '[' std::vector<unsigned> Ranges = ParseRangeList(); if (Ranges.empty()) return 0; Result = Result->convertInitListSlice(Ranges); if (Result == 0) { Error(SquareLoc, "Invalid range for list slice"); return 0; } // Eat the ']'. if (Lex.getCode() != tgtok::r_square) { TokError("expected ']' at end of list slice"); return 0; } Lex.Lex(); break; } case tgtok::period: if (Lex.Lex() != tgtok::Id) { // eat the . TokError("expected field identifier after '.'"); return 0; } if (!Result->getFieldType(Lex.getCurStrVal())) { TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + Result->getAsString() + "'"); return 0; } Result = new FieldInit(Result, Lex.getCurStrVal()); Lex.Lex(); // eat field name break; } } }
int main(void) { srand(time(NULL)); //Create init object Init init = Init(); //Initialize glfw init.glfw(4, 1); //Open a window GLFWwindow *window = init.window(400, 400); //Print window info init.printWindowInfo(window); //Make opened window current context glfwMakeContextCurrent(window); init.glew(); int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); glEnable(GL_CULL_FACE); // Nvidia cards require a vertex array to cooperate. GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); //Set up the initial state. unsigned int w = 32, h = 32, d = 32; State *prevState = new State(w, h, d); VelocityGrid *velocities = new VelocityGrid(w, h, d); prevState->setVelocityGrid(velocities); // init level set LevelSet *ls = factory::levelSet::ball(w, h, d); prevState->setLevelSet(ls); delete ls; // init simulator Simulator sim(*prevState, 0.1f); // BubbleMaxExporter bubbleExporter; // Dark black background glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Load in shaders static ShaderProgram colorCubeProg("../vertShader.vert", "../colorCube.frag"); static ShaderProgram rayCasterProg("../vertShader.vert", "../rayCaster.frag"); static ShaderProgram bubbleProg("../bubbleVertShader.vert", "../bubbleFragShader.frag"); static const GLfloat vertexBufferData[] = { -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; static const GLuint triangleBufferData[] = { // xy plane (z = -1) 0, 1, 3, 3, 2, 0, // xz plane (y = -1) 0, 5, 1, 0, 4, 5, // yz plane (x = -1) 0, 2, 4, 2, 6, 4, // xy plane (z = 1) 4, 7, 5, 4, 6, 7, // xz plane (y = 1) 2, 7, 6, 2, 3, 7, // yz plane (x = 1) 1, 5, 3, 3, 5, 7 }; std::vector<GLfloat> g_bubble_buffer_data; //Create vertex buffer GLuint vertexbuffer; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexBufferData), vertexBufferData, GL_STATIC_DRAW); GLuint triangleBuffer; glGenBuffers(1, &triangleBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(triangleBufferData), triangleBufferData, GL_STATIC_DRAW); // Create bubble buffer GLuint bubbleBuffer; glGenBuffers(1, &bubbleBuffer); // Create framebuffer FBO *framebuffer = new FBO(width, height); GLuint volumeTextureId; glGenTextures(1, &volumeTextureId); glBindTexture(GL_TEXTURE_3D, volumeTextureId); //Object which encapsulates a texture + The destruction of a texture. Texture3D tex3D(w, h, d); double lastTime = glfwGetTime(); int nbFrames = 0; float deltaT = 0.1; //First time step glfwSwapInterval(1); int i = 0; do { framebuffer->activate(); // common for both render passes. sim.step(deltaT); // deltaT = sim.getDeltaT(); glm::mat4 matrix = glm::mat4(1.0f); matrix = glm::translate(matrix, glm::vec3(0.0f, 0.0f, 2.0f)); matrix = glm::rotate(matrix, -3.1415926535f / 4.0f, glm::vec3(1.0f, 0.0f, 0.0f)); matrix = glm::rotate(matrix, 0.1415926535f / 4.0f * (float) glfwGetTime(), glm::vec3(0.0f, 1.0f, 0.0f)); // Render back face of the cube. colorCubeProg(); glCullFace(GL_FRONT); { GLuint tLocation = glGetUniformLocation(colorCubeProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(colorCubeProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); } glClear(GL_COLOR_BUFFER_BIT); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleBuffer); //Triangle coordinates glVertexAttribPointer( 0, // Location 0 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *) 0 // array buffer offset ); glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); // Do the ray casting. glBindFramebuffer(GL_FRAMEBUFFER, 0); // bind the screen glCullFace(GL_BACK); rayCasterProg(); { GLuint tLocation = glGetUniformLocation(rayCasterProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(rayCasterProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); GLuint windowSizeLocation = glGetUniformLocation(rayCasterProg, "windowSize"); glUniform2f(windowSizeLocation, width, height); } glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, *(framebuffer->getTexture())); GLuint textureLocation = glGetUniformLocation(rayCasterProg, "backfaceTexture"); glUniform1i(textureLocation, 0); State *currentState = sim.getCurrentState(); std::vector<glm::vec3> vertexList; std::vector<std::vector<int> > faceIndices; // copy desired quantities to texture for (unsigned int k = 0; k < d; ++k) { for (unsigned int j = 0; j < h; ++j) { for (unsigned int i = 0; i < w; ++i) { // velocity //tex3D.set(i,j,k,0, 0.5 + 0.5*currentState.getVelocityGrid()->u->get(i,j,k)); //tex3D.set(i,j,1, 0.5 + 0.5*currentState.getVelocityGrid()->v->get(i,j)); //tex3D.set(i,j,2, 0.5 + currentState.getCellTypeGrid()->get(i, j)); //tex3D.set(i,j,2, 0.5); //tex3D.set(i,j,3, 1.0f); // divergence //tex3D.set(i,j,0, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,1, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,2, fabs(sim.getDivergenceGrid()->get(i,j))); //tex3D.set(i,j,3, 1.0f); // type // tex3D.set(i,j,k, 0, currentState.getCellTypeGrid()->get(i,j, k) == CellType::FLUID ? 1.0 : 0.0); // tex3D.set(i,j,k, 1, currentState.getCellTypeGrid()->get(i,j, k) == CellType::FLUID ? 1.0 : 0.0); // tex3D.set(i,j,k, 2, currentState.getCellTypeGrid()->get(i,j, k) == CellType::SOLID ? 1.0 : 0.0); // tex3D.set(i,j,k, 3, 1.0f); if(currentState->getSignedDistanceGrid()->isValid(i+1,j,k) && currentState->getSignedDistanceGrid()->isValid(i,j+1,k) && currentState->getSignedDistanceGrid()->isValid(i+1,j+1,k) && currentState->getSignedDistanceGrid()->isValid(i,j,k+1) && currentState->getSignedDistanceGrid()->isValid(i+1,j,k+1) && currentState->getSignedDistanceGrid()->isValid(i,j+1,k+1) && currentState->getSignedDistanceGrid()->isValid(i+1,j+1,k+1)){ marchingCubes::GRIDCELL gridcell; gridcell.p[0] = glm::vec3(i,j,k); gridcell.p[1] = glm::vec3(i,j+1,k); gridcell.p[2] = glm::vec3(i+1,j+1,k); gridcell.p[3] = glm::vec3(i+1,j,k); gridcell.p[4] = glm::vec3(i,j,k+1); gridcell.p[5] = glm::vec3(i,j+1,k+1); gridcell.p[6] = glm::vec3(i+1,j+1,k+1); gridcell.p[7] = glm::vec3(i+1,j,k+1); gridcell.val[0] = currentState->getSignedDistanceGrid()->get(i, j, k); gridcell.val[1] = currentState->getSignedDistanceGrid()->get(i, j+1, k); gridcell.val[2] = currentState->getSignedDistanceGrid()->get(i+1, j+1, k); gridcell.val[3] = currentState->getSignedDistanceGrid()->get(i+1, j, k); gridcell.val[4] = currentState->getSignedDistanceGrid()->get(i, j, k+1); gridcell.val[5] = currentState->getSignedDistanceGrid()->get(i, j+1, k+1); gridcell.val[6] = currentState->getSignedDistanceGrid()->get(i+1, j+1, k+1); gridcell.val[7] = currentState->getSignedDistanceGrid()->get(i+1, j, k+1); //std::cout << gridcell.val[0] << std::endl; marchingCubes::TRIANGLE *triangles = new marchingCubes::TRIANGLE[5]; int numTriangles = marchingCubes::PolygoniseCube(gridcell, 0.0, triangles); for(int i = 0; i < numTriangles; i++){ int startIndex = vertexList.size()+1; for(int j = 0; j < 3; j++){ //std::cout << triangles[i].p[j].x << " " << triangles[i].p[j].y << " " << triangles[i].p[j].z << std::endl; } vertexList.push_back(triangles[i].p[0]); vertexList.push_back(triangles[i].p[1]); vertexList.push_back(triangles[i].p[2]); std::vector<int> indices = { startIndex, startIndex+1, startIndex+2 }; faceIndices.push_back(indices); } delete[] triangles; } //signed dist float dist = currentState->getSignedDistanceGrid()->get(i, j, k); float solid = currentState->getCellTypeGrid()->get(i, j, k) == CellType::SOLID ? 1.0f : 0.0f; dist = (glm::clamp(dist + solid, -1.0f, 1.0f) + 1) / 2; tex3D.set(i, j, k, 0, solid); tex3D.set(i, j, k, 1, 0.0f); // not used tex3D.set(i, j, k, 2, dist); tex3D.set(i, j, k, 3, 1.0f); //closest point // tex3D.set(i,j,0, currentState.getClosestPointGrid()->get(i,j).x / 70.0); // tex3D.set(i,j,1, currentState.getClosestPointGrid()->get(i,j).y / 70.0); // tex3D.set(i,j,2, 0.0f); // tex3D.set(i,j,3, 1.0f); } } } printObjToFile("exported_" + std::to_string(i) + ".obj", vertexList, faceIndices); std::ofstream fileStream("exportedState_" + std::to_string(i) + ".pf", std::ios::binary); currentState->write(fileStream); fileStream.close(); // activate and upload texture to gpu tex3D(GL_TEXTURE1); GLuint volumeTextureLocation = glGetUniformLocation(rayCasterProg, "volumeTexture"); glUniform1i(volumeTextureLocation, 1); glEnableVertexAttribArray(0); glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); FBO::deactivate(); ////////////////// Start drawing bubbles ////////////////////// // Draw bubbles const std::vector<Bubble> bubbles = currentState->getBubbles(); g_bubble_buffer_data.clear(); std::cout << "frame=" << i << ", nBubbles=" << bubbles.size() << std::endl; for (int i = 0; i < bubbles.size(); i++) { Bubble b = bubbles.at(i); // std::cout << "bubble pos " << b.position.x << ", " << b.position.y << std::endl << b.radius << std::endl; g_bubble_buffer_data.push_back(b.position.x / (float)w * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.position.y / (float)h * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.position.z / (float)d * 2.0 - 1.0); g_bubble_buffer_data.push_back(b.radius); } glBindBuffer(GL_ARRAY_BUFFER, bubbleBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * g_bubble_buffer_data.size(), &g_bubble_buffer_data[0], GL_DYNAMIC_DRAW); bubbleProg(); glEnable(GL_PROGRAM_POINT_SIZE); { GLuint tLocation = glGetUniformLocation(colorCubeProg, "time"); glUniform1f(tLocation, glfwGetTime()); GLuint mvLocation = glGetUniformLocation(colorCubeProg, "mvMatrix"); glUniformMatrix4fv(mvLocation, 1, false, glm::value_ptr(matrix)); } // glEnable (GL_BLEND); // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPointSize(4.0); if (g_bubble_buffer_data.size() > 0) { glEnable(GL_PROGRAM_POINT_SIZE); glEnableVertexAttribArray(0); glVertexAttribPointer( 0, //Location 0 4, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glDrawArrays(GL_POINTS, 0, 4 * g_bubble_buffer_data.size()); // 3 indices starting at 0 -> 1 triangle glDisableVertexAttribArray(0); } ////////////////// End drawing bubbles ////////////////////// glfwPollEvents(); glfwSwapBuffers(window); double currentTime = glfwGetTime(); nbFrames++; if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1 sec ago // printf and reset timer std::string title = std::to_string(1000.0 / double(nbFrames)) + "ms/frame " + std::to_string(deltaT) + " dt"; glfwSetWindowTitle(window, title.c_str()); nbFrames = 0; lastTime += 1.0; } i++; // bubbleExporter.update(i, sim.getBubbleTracker()); // bubbleExporter.exportSnapshot(i, "bubbles_" + std::to_string(i) + ".mx"); /* if (i > 600) { bubbleExporter.exportBubbles("bubbles.mx"); break; }*/ } // Check if the ESC key was pressed or the window was closed while (!glfwWindowShouldClose(window)); std::cout << "Cleaning up!" << std::endl; // Close OpenGL window and terminate GLFW glfwDestroyWindow(window); glfwTerminate(); glDeleteBuffers(1, &vertexbuffer); glDeleteVertexArrays(1, &VertexArrayID); exit(EXIT_SUCCESS); }