int main(int argc, char **argv){ generateSlope();//generates slope vertices and normals into an array generateTrees(); generateParticles(ski1.particles.snow); generateParticles(ski2.particles.snow); setSlopeBoundary(&ski1, 0, X_WAVE_INCREMENT, 0, Z_WAVE_INCREMENT); setSlopeBoundary(&ski2, 0, X_WAVE_INCREMENT, 0, Z_WAVE_INCREMENT); //orientateSkier();//determine skier's starting orientation glutInit(&argc, argv); /*output functions*/ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); window = glutCreateWindow("Skier"); glOrtho(-1,1,-1,1,-1,1); glEnable(GL_DEPTH_TEST); //glDisable(GL_DEPTH_TEST); glutDisplayFunc(display); glutIdleFunc(idle); glutReshapeFunc(reshape); /*input functions*/ glutMotionFunc(mouseMove); glutMouseFunc(mouseState); glutPassiveMotionFunc(mousePassiveMove); glutKeyboardFunc(keyDown); glutKeyboardUpFunc(keyUp); glutSpecialFunc(arrowKeys); glutSpecialUpFunc(arrowKeys); /*load textures*/ snowTexture = loadTexture("texture/snow.jpg", ON); trees.texture = loadTexture("texture/tree.png", OFF); snowballTexture = loadTexture("texture/snowball.png", OFF); initSkyBox(); glutMainLoop(); return EXIT_SUCCESS; }
// This function is finding the right thing to do based on the time that we are in void doTheScripting(long itime) { while (itime >= sceneStartTime + sceneDuration) { sceneStartTime += sceneDuration; sceneNumber++; } int sceneID = sceneNumber; // That's the easiest thing, really int sceneTime = itime - sceneStartTime; // Create the stuff based on the current timing thing transformationSeed = sceneID; createTransforms((float)sceneTime / 44100.0f); buildTree(); generateParticles(); transformationSeed = sceneID; generateOGLTransforms((float)sceneTime / (float)sceneDuration); }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QGLFormat glFormat; glFormat.setVersion(3, 3); glFormat.setProfile(QGLFormat::CoreProfile); glFormat.setSampleBuffers(true); viewer = new ModelViewer(glFormat, this); connect(viewer, SIGNAL(openGLInitialized()), this, SLOT(setTerrain())); //-------------------------------------------------------------------------------- QGroupBox *gbStaticOptions = new QGroupBox("Static", this); gbStaticOptions->setFlat(true); sbPCount = new QSpinBox(this); sbPCount->setRange(4, 100000); sbPCount->setSingleStep(50); sbPCount->setValue(10000); sbPSSize = new QSpinBox(this); sbPSSize->setRange(50, 1000); sbPSSize->setSingleStep(50); sbPSSize->setValue(400); sbTCSize = new QSpinBox(this); sbTCSize->setRange(1, 400); sbTCSize->setSingleStep(1); sbTCSize->setValue(2); QGridLayout *statLayout = new QGridLayout(); statLayout->setContentsMargins(0, 0, 0, 0); statLayout->setSpacing(5); statLayout->setColumnStretch(0, 0); statLayout->setColumnStretch(1, 1); statLayout->addWidget(new QLabel("Max particles:", this), 1, 0); statLayout->addWidget(sbPCount, 1, 1); statLayout->addWidget(new QLabel("Cube size:", this), 2, 0); statLayout->addWidget(sbPSSize, 2, 1); statLayout->addWidget(new QLabel("Terrain grid size:", this), 3, 0); statLayout->addWidget(sbTCSize, 3, 1); gbStaticOptions->setLayout(statLayout); //-------------------------------------------------------------------------------- QGroupBox *gbDynamicOptions = new QGroupBox("Dynamic", this); gbDynamicOptions->setFlat(true); QComboBox *cbBType = new QComboBox(this); cbBType->addItem("perspective"); cbBType->addItem("fixed size"); cbBType->setCurrentIndex(0); connect(cbBType, SIGNAL(currentIndexChanged(int)), viewer, SLOT(setBillboardType(int))); sbTDist = new QDoubleSpinBox(this); sbTDist->setRange(0, 100); sbTDist->setSingleStep(1); sbTDist->setValue(50); connect(sbTDist, SIGNAL(valueChanged(double)), viewer, SLOT(setDistanceThreshold(double))); QCheckBox *cbShowTerrain = new QCheckBox("Show skybox", this); cbShowTerrain->setChecked(true); connect(cbShowTerrain, SIGNAL(toggled(bool)), viewer, SLOT(setShowTerrain(bool))); QCheckBox *cbShowWireframe = new QCheckBox("Wireframe", this); cbShowWireframe->setChecked(false); connect(cbShowWireframe, SIGNAL(toggled(bool)), viewer, SLOT(setWireframeMode(bool))); QPushButton *pbGenerate = new QPushButton("Generate", this); connect(pbGenerate, SIGNAL(clicked()), this, SLOT(generateParticles())); QGridLayout *dynLayout = new QGridLayout(); dynLayout->setContentsMargins(0, 0, 0, 0); dynLayout->setSpacing(5); dynLayout->setColumnStretch(0, 0); dynLayout->setColumnStretch(1, 1); dynLayout->addWidget(new QLabel("Billboard type:", this), 0, 0); dynLayout->addWidget(cbBType, 0, 1); dynLayout->addWidget(new QLabel("Thres distance:", this), 1, 0); dynLayout->addWidget(sbTDist, 1, 1); dynLayout->addWidget(cbShowTerrain, 2, 0, 1, 2); dynLayout->addWidget(cbShowWireframe, 3, 0, 1, 2); dynLayout->addWidget(pbGenerate, 4, 0, 1, 2); gbDynamicOptions->setLayout(dynLayout); //-------------------------------------------------------------------------------- QGroupBox *gbTerrainOptions = new QGroupBox("Terrain", this); gbTerrainOptions->setFlat(true); cbTerrainTexture = new QComboBox(this); cbTerrainTexture->addItem("texture 1"); connect(cbTerrainTexture, SIGNAL(currentIndexChanged(int)), this, SLOT(setTerrainTexture(int))); QComboBox *cbTerrainMode = new QComboBox(this); cbTerrainMode->addItem("texture"); cbTerrainMode->addItem("normal"); cbTerrainMode->addItem("facet norm."); cbTerrainMode->addItem("vertex norm."); connect(cbTerrainMode, SIGNAL(currentIndexChanged(int)), viewer, SLOT(setTerrainTexMode(int))); QDoubleSpinBox *sbContrast = new QDoubleSpinBox(this); sbContrast->setRange(0.1, 10.0); sbContrast->setSingleStep(0.1); sbContrast->setValue(1.0); connect(sbContrast, SIGNAL(valueChanged(double)), viewer, SLOT(setTerrainContrast(double))); sbTPers = new QSpinBox(this); sbTPers->setRange(1, 500); // sbTPers->setSingleStep(10); sbTPers->setValue(10); sbTFreq = new QSpinBox(this); sbTFreq->setRange(1, 500); // sbTFreq->setSingleStep(10); sbTFreq->setValue(10); sbTAmp = new QDoubleSpinBox(this); sbTAmp->setRange(0.1, 100.0); sbTAmp->setValue(30.0); sbTOct = new QSpinBox(this); sbTOct->setRange(1, 10); sbTOct->setValue(3); QPushButton *pbUpdateTerrain = new QPushButton("Update terrain", this); connect(pbUpdateTerrain, SIGNAL(clicked()), this, SLOT(generateTerrain())); QGridLayout *terLayout = new QGridLayout(); terLayout->setContentsMargins(0, 0, 0, 0); terLayout->setSpacing(5); terLayout->addWidget(new QLabel("Texture:", this), 0, 0); terLayout->addWidget(cbTerrainTexture, 0, 1); terLayout->addWidget(new QLabel("Mode:", this), 1, 0); terLayout->addWidget(cbTerrainMode, 1, 1); terLayout->addWidget(new QLabel("Contrast:", this), 2, 0); terLayout->addWidget(sbContrast, 2, 1); terLayout->addWidget(new QLabel("Persistence:", this), 3, 0); terLayout->addWidget(sbTPers, 3, 1); terLayout->addWidget(new QLabel("Frequency:", this), 4, 0); terLayout->addWidget(sbTFreq, 4, 1); terLayout->addWidget(new QLabel("Amplitude:", this), 5, 0); terLayout->addWidget(sbTAmp, 5, 1); terLayout->addWidget(new QLabel("Octaves:", this), 6, 0); terLayout->addWidget(sbTOct, 6, 1); terLayout->addWidget(pbUpdateTerrain, 7, 0, 1, 2); gbTerrainOptions->setLayout(terLayout); //-------------------------------------------------------------------------------- QGroupBox *gbCameraOptions = new QGroupBox("Camera", this); gbCameraOptions->setFlat(true); cbCameraMode = new QCheckBox("Single camera", this); cbCameraMode->setChecked(true); connect(cbCameraMode, SIGNAL(toggled(bool)), this, SLOT(setCameraMode(bool))); cbCurrentCamera = new QComboBox(this); cbCurrentCamera->addItem("particles"); cbCurrentCamera->addItem("free"); cbCurrentCamera->setEnabled(false); connect(cbCurrentCamera, SIGNAL(currentIndexChanged(int)), viewer, SLOT(setCurrentCamera(int))); QGridLayout *camLayout = new QGridLayout(); camLayout->setContentsMargins(0, 0, 0, 0); camLayout->setSpacing(5); camLayout->addWidget(cbCameraMode, 0, 0, 1, 2); camLayout->addWidget(new QLabel("Camera:", this), 1, 0); camLayout->addWidget(cbCurrentCamera, 1, 1); gbCameraOptions->setLayout(camLayout); //-------------------------------------------------------------------------------- QGroupBox *gbOptions = new QGroupBox("Options", this); QGridLayout *optLayout = new QGridLayout(); optLayout->setSpacing(5); optLayout->setContentsMargins(5, 5, 5, 5); optLayout->setColumnStretch(0, 0); optLayout->setColumnStretch(1, 1); optLayout->addWidget(gbStaticOptions, 0, 0, 1, 2); optLayout->addWidget(gbDynamicOptions, 1, 0, 1, 2); optLayout->addWidget(gbTerrainOptions, 3, 0, 1, 2); optLayout->addWidget(gbCameraOptions, 4, 0, 1, 2); optLayout->setRowStretch(2, 1); gbOptions->setLayout(optLayout); QWidget *w = new QWidget(this); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(5, 5, 5, 5); layout->setSpacing(5); layout->addWidget(viewer, 1); layout->addWidget(gbOptions, 0); w->setLayout(layout); this->setCentralWidget(w); this->setWindowTitle("CG Task 4"); }
void ParticleSystem::update(f32 dt, math::Vec2 forces) //1.Update particles age //2.Remove dead particles //3.Update pre-existent particles speed, position, color, rotation, etc //4.Add generated particles { std::list<Particle *>::iterator it; it=particles.begin(); //For each particle while(it != particles.end()) { Particle *particle = *it; //1.update particles age particle->age+=dt; //2.Remove dead particles if ( this->particleLifeTime != UNLIMITED_PARTICLE_LIFE ) { if ( (particle->age) > (this->particleLifeTime) ) { it=particles.erase(it); this->particlePool.destroy(particle); continue; } } //3.Update pre-existent particles speed, position, color, rotation, etc particle->speed+= dt * forces; particle->position+= dt * particle->speed; particle->rotationSpeed+= dt * this->particleRotationFriction; particle->rotation+= dt * particle->rotationSpeed; particle->color.x+= dt * this->particleColorDecay.x; particle->color.y+= dt * this->particleColorDecay.y; particle->color.z+= dt * this->particleColorDecay.z; particle->color.w+= dt * this->particleColorDecay.w; //Next particle ++it; } //4.Add generated particles this->timeAfterLastSpawning+=dt; if ( (this->capacity == UNLIMITED_CAPACITY) || (this->remainingParticleCount != 0) ) { u32 particleToSpawnCount=0; while ( this->timeAfterLastSpawning >= this->timeBetweenTwoSpawns) { this->timeAfterLastSpawning-=this->timeBetweenTwoSpawns; ++particleToSpawnCount; } if ( this->capacity == UNLIMITED_CAPACITY ) { generateParticles(particleToSpawnCount); } else if (particleToSpawnCount < (this->remainingParticleCount) ) { generateParticles(particleToSpawnCount); this->remainingParticleCount -= particleToSpawnCount; } else { generateParticles(this->remainingParticleCount); this->remainingParticleCount=0; } } }
void Scene::read(const char *filename) { QString path; if(!filename) path = QString("./data/scenes/open/"); else path = "./data/scenes/"+QString(filename)+"/"; //Parsing XML document. QDomDocument dom("config"); QFile xml_doc(path+"config.xml"); if(!xml_doc.open(QIODevice::ReadOnly)) { QMessageBox::warning(NULL, QString("Read ")+filename+QString(" config"), QString("Can't open the file config.xml of ")+filename); return; } if (!dom.setContent(xml_doc.readAll())) { xml_doc.close(); QMessageBox::warning(NULL, QString("Read ")+filename+QString(" config"), "Le document XML n'a pas pu être attribué à l'objet QDomDocument."); return; } xml_doc.close(); //Count layers QDomNode node = dom.documentElement().firstChild(); while(!node.isNull()) { QDomElement element = node.toElement(); if(element.tagName() == "layer") m_nbLayer++; if(element.tagName() == "copy") m_nbCopy++; node = node.nextSibling(); } //Init new layers & copyers m_layer = new Layer[m_nbLayer]; for(int i=0; i<m_nbLayer; i++) { m_layer[i].shader = NULL; m_layer[i].buffer = NULL; m_layer[i].backBuffer = NULL; m_layer[i].tmpBuffer = NULL; m_layer[i].mode = DEFAULT; for(int j=0; j<4; j++) { m_layer[i].channel[j] = NULL; } } m_copy = new Copy[m_nbCopy]; for(int i=0; i<m_nbCopy; i++) { m_copy[i].src = NULL; m_copy[i].dest = NULL; } //Read the xml file node = dom.documentElement().firstChild(); int textureID=0; while(!node.isNull()) { QDomElement element = node.toElement(); if(element.tagName() == "copy") { int id = element.attribute("id", "0").toInt(); int src = element.attribute("src", "0").toInt(); int dest = element.attribute("dest", "0").toInt(); m_copy[id].src = m_layer[src].buffer; m_copy[id].dest = m_layer[dest].backBuffer; } else if(element.tagName() == "layer") { //Get infos .. int id = element.attribute("id", "0").toInt(); QString format = element.attribute("format", "rgba"); QString blend = element.attribute("mode", "default"); m_layer[id].width = element.attribute("width", "-1").toInt(); m_layer[id].height = element.attribute("height", "-1").toInt(); QString type = element.attribute("type", "pixel"); if(type == "pixel") m_layer[id].type = PIXEL; else if(type == "particle") { m_layer[id].type = PARTICLE; m_nbParticles = element.attribute("count", "0").toInt(); generateParticles(); } m_layer[id].iterate = element.attribute("iterate", "0").toInt(); if(m_layer[id].width == -1) m_layer[id].width = Core::instance()->getResX(); if(m_layer[id].height == -1) m_layer[id].height = Core::instance()->getResY(); if(blend != "default") { m_layer[id].tmpBuffer = new FBO(); m_layer[id].tmpBuffer->setSize(m_layer[id].width, m_layer[id].height); } //Select format GLint bufferFormat = GL_RGBA; if(format == "rgb") bufferFormat = GL_RGB; else if(format == "rgba") bufferFormat = GL_RGBA; else if(format == "rgba32") bufferFormat = GL_RGBA32F_ARB; //work ? else if(format == "rgba32") bufferFormat = GL_RGBA32F_ARB; //work ? else if(format == "rgba32half") bufferFormat = GL_RGBA16F_ARB; //work ? else if(format == "luminance") bufferFormat = GL_LUMINANCE; else QMessageBox::warning(NULL, QString("Scene ")+filename, QString("This layer format doesn't exist : ")+format); //Select mode if(blend == "default") m_layer[id].mode = DEFAULT; else if(blend == "alpha") m_layer[id].mode = BLEND_ALPHA; else if(blend == "add") m_layer[id].mode = BLEND_ADD; else if(blend == "none") m_layer[id].mode = NONE; else QMessageBox::warning(NULL, QString("Scene ")+filename, QString("This layer mode doesn't exist : ")+blend); //Compute shader QString filePath = element.attribute("value", "none"); m_layer[id].name = filePath; int ok; if(filePath != "none") { QFile file(path+filePath); QString strings; if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); while (!in.atEnd()) { strings += in.readLine()+"\n"; } } Core::instance()->writeInfo( QString("Compiling ") + m_layer[id].name + QString(".. ") ); m_layer[id].shader = new Shader(); if( m_layer[id].type == PIXEL) ok = m_layer[id].shader->compil(Core::instance()->getVertexShader(),strings.toStdString().c_str()); else if( m_layer[id].type == PARTICLE) ok = m_layer[id].shader->compil(Core::instance()->getVertexShaderParticle(),strings.toStdString().c_str()); if(ok == SHADER_SUCCESS) Core::instance()->writeInfo( QString("[Done]\n"), false ); file.close(); } //Generate buffers ! if(ok == SHADER_SUCCESS) { m_layer[id].buffer = new FBO(); m_layer[id].buffer->setSize(m_layer[id].width, m_layer[id].height); m_layer[id].buffer->setFormat(bufferFormat); if(element.attribute("backbuffer", "false") == "true" || m_layer[id].iterate > 0) { m_layer[id].backBuffer = new FBO(); m_layer[id].backBuffer->setSize(m_layer[id].width, m_layer[id].height); m_layer[id].backBuffer->setFormat(bufferFormat); } } else { return; } //Load channel textureID=0; QDomNode n = element.firstChild(); while(!n.isNull()) { QDomElement e = n.toElement(); if(e.tagName() == "channel") { if(textureID<4) { m_layer[id].channelName[textureID] = e.attribute("id", "tex"); if( e.attribute("type", "") == "image" ) { m_layer[id].channel[textureID] = new Texture(); m_layer[id].channel[textureID]->load("./data/textures/"+e.attribute("value", "none").toStdString()); } else if( e.attribute("type", "") == "layer" ) { m_layer[id].channel[textureID] = m_layer[e.attribute("value", "0").toInt()].buffer; m_layer[e.attribute("value", "0").toInt()].buffer->bind(); } textureID++; } else QMessageBox::warning(NULL, QString("Read ")+filename+QString(" config"), QString("Too many textures (max is 4)")); } n = n.nextSibling(); } } else if(element.tagName() == "param") { m_param[element.attribute("id", "0").toInt()] = element.attribute("value","none"); } node = node.nextSibling(); } }