diff --git a/mainwindow.ui b/mainwindow.ui index c7a20fe..d70d07a 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -174,8 +174,30 @@ + + + Filtrage + + + + Mag Filter + + + + + + + Min Filter + + + + + + + + @@ -220,6 +242,38 @@ Gouraud + + + true + + + Nearest + + + + + true + + + Linear + + + + + true + + + Nearest + + + + + true + + + Linear MipMap Linear + + diff --git a/src/glnodes/glnode.h b/src/glnodes/glnode.h index 6d88ffc..db77932 100644 --- a/src/glnodes/glnode.h +++ b/src/glnodes/glnode.h @@ -4,10 +4,13 @@ #include "../interfaces/ivisitable.h" #include "../interfaces/visitor.h" class Viewer; +class SceneGroup; class GlNode : public IVisitable { public: QMatrix4x4 transform; + virtual SceneGroup* getParent() = 0; + virtual void setParent(SceneGroup* s) = 0; }; #endif // GLNODE diff --git a/src/glnodes/scenegroup.cpp b/src/glnodes/scenegroup.cpp index 551339d..f9124bb 100644 --- a/src/glnodes/scenegroup.cpp +++ b/src/glnodes/scenegroup.cpp @@ -32,7 +32,7 @@ bool SceneGroup::hasNext() } void SceneGroup::addChild(GlNode* child){ - + child->setParent(this); children.push_back(child); //children.push_back(std::shared_ptr(child)); } @@ -40,3 +40,11 @@ void SceneGroup::addChild(GlNode* child){ void SceneGroup::accept(Visitor &v) { v.visit(*this); } + +SceneGroup* SceneGroup::getParent() { + return _parent; +} + +void SceneGroup::setParent(SceneGroup* s) { + _parent = s; +} diff --git a/src/glnodes/scenegroup.h b/src/glnodes/scenegroup.h index 9296bed..8008fef 100644 --- a/src/glnodes/scenegroup.h +++ b/src/glnodes/scenegroup.h @@ -10,6 +10,7 @@ class SceneGroup : public GlNode private: std::vector children; int childIndex = 0; + SceneGroup* _parent; public: void addChild(GlNode* c); GlNode* getChild(); @@ -19,6 +20,9 @@ public: GlNode* childAt(int i); + SceneGroup* getParent(); + void setParent(SceneGroup* s); + void accept(Visitor& v) override; SceneGroup(); }; diff --git a/src/glnodes/shapes.cpp b/src/glnodes/shapes.cpp index e03cc4b..f886192 100644 --- a/src/glnodes/shapes.cpp +++ b/src/glnodes/shapes.cpp @@ -17,6 +17,14 @@ void Cube::setColor(QColor& c) { color = QColor(c); } +SceneGroup* Cube::getParent() { + return _parent; +} + +void Cube::setParent(SceneGroup* c) { + _parent = c; +} + QColor Cube::getColor(){ return color; }; @@ -41,6 +49,14 @@ void Sphere::setType(int t) { this->type = t; } +SceneGroup* Sphere::getParent() { + return _parent; +} + +void Sphere::setParent(SceneGroup* c) { + _parent = c; +} + int Sphere::getType(){ return this->type; }; diff --git a/src/glnodes/shapes.h b/src/glnodes/shapes.h index 5f53a31..acd4184 100644 --- a/src/glnodes/shapes.h +++ b/src/glnodes/shapes.h @@ -4,6 +4,7 @@ #include #include #include "../interfaces/visitor.h" +class SceneGroup; class Shape : public GlNode { public: @@ -11,12 +12,15 @@ public: virtual QColor getColor() = 0; virtual void setType(int) = 0; virtual int getType() = 0; + virtual SceneGroup* getParent() = 0; + virtual void setParent(SceneGroup* s) = 0; }; class Cube : public Shape { private: int type = 0; + SceneGroup* _parent; public: Cube(){} QColor color; @@ -25,12 +29,15 @@ public: QColor getColor(); void setType(int); int getType(); + SceneGroup* getParent(); + void setParent(SceneGroup* s); }; class Sphere : public Shape { private: int type = 0; + SceneGroup* _parent; public: Sphere(){} QColor color; @@ -39,5 +46,7 @@ public: QColor getColor(); void setType(int); int getType(); + SceneGroup* getParent(); + void setParent(SceneGroup* s); }; #endif // SHAPES_H diff --git a/src/shaders/basicShader.frag b/src/shaders/basicShader.frag index edb83e1..1a47f79 100644 --- a/src/shaders/basicShader.frag +++ b/src/shaders/basicShader.frag @@ -89,10 +89,10 @@ main() vec3 nfNormal = normalize(fNormal); vec3 nviewDirection = normalize(fPosition); - fColor = calcDirLight(texColor, fPosition, fNormal) - + calcPointLight(texColor, fPosition, fNormal, 0)/4 - + calcPointLight(texColor, fPosition, fNormal, 1)/4 - + calcPointLight(texColor, fPosition, fNormal, 2)/4; + fColor = calcDirLight(texColor, fPosition, fNormal) + + calcPointLight(texColor, fPosition, fNormal, 0)/4 + + calcPointLight(texColor, fPosition, fNormal, 1)/4 + + calcPointLight(texColor, fPosition, fNormal, 2)/4; } else { fColor = texColor + ifColor; } diff --git a/src/viewer/simpleViewer.cpp b/src/viewer/simpleViewer.cpp index 383ebcf..1313213 100644 --- a/src/viewer/simpleViewer.cpp +++ b/src/viewer/simpleViewer.cpp @@ -61,6 +61,7 @@ namespace QMatrix4x4 sunRotate; SceneGroup* selection; + PickedGeom selectedObj; int currentPoint = 0; // VERY lazy way of tracking light balls } @@ -187,17 +188,32 @@ void Viewer::mousePressEvent(QMouseEvent* e) { std::cout << "--------------------------------------------------\nPicking shape at " << x << " (" << this->x() << " + " << e->x() << "), " << y << endl; std::cout << "Window geom: " << this->window()->size().width() << "w, " << this->window()->size().height() << "h" << endl; - QMatrix4x4 selectedPosition = pickGeom(x, y); - if(!selectedPosition.isIdentity() && e->modifiers().testFlag(Qt::ShiftModifier)) - { - Cube* c = new Cube; - c->setType(TEX_WOODFLOOR); - SceneGroup* container = new SceneGroup; - //selectedPosition.copyDataTo(container->transform.data()); - container->transform = selectedPosition; - container->addChild(c); - root.addChild(container); - } else QGLViewer::mousePressEvent(e); + PickedGeom selectedGeom = pickGeom(x, y); + + if(!selectedGeom.position.isIdentity() && e->modifiers().testFlag(Qt::ControlModifier)) + { + if(selectedObj.shape->getParent() != nullptr) { + // Remove previous selection + selectedObj.shape->getParent()->getChildren()->erase( + std::remove(selectedObj.shape->getParent()->getChildren()->begin(), + selectedObj.shape->getParent()->getChildren()->end(), + selection), + selectedObj.shape->getParent()->getChildren()->end()); + } + selectedObj.shape = selectedGeom.shape; + selectedObj.shape->getParent()->addChild(selection); + } + + if(!selectedGeom.position.isIdentity() && e->modifiers().testFlag(Qt::ShiftModifier)) + { + Cube* c = new Cube; + c->setType(TEX_WOODFLOOR); + SceneGroup* container = new SceneGroup; + //selectedPosition.copyDataTo(container->transform.data()); + container->transform = selectedGeom.position; + container->addChild(c); + root.addChild(container); + } else QGLViewer::mousePressEvent(e); } void Viewer::mouseReleaseEvent(QMouseEvent* e) { @@ -236,6 +252,8 @@ void Viewer::init() { + // Default non existant cube + selectedObj.shape = new Cube(); QColor* c1 = new QColor(255, 0, 255, 255); QColor* c2 = new QColor(0, 255, 255, 255); @@ -252,8 +270,7 @@ void Viewer::init() //SceneGroup *sc1 = new SceneGroup(); //sc1->addChild(selection); - //root.addChild(sc1); - root.addChild(selection); + //root.addChild(sc1); s1->transform.rotate(360 * 1/3,0,1,0); s1->transform.translate(0.3,1,0); @@ -268,7 +285,6 @@ void Viewer::init() s3->transform.scale(0.05); s3->setColor(*c3); - for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ Shape* cube = new Cube(); @@ -284,6 +300,23 @@ void Viewer::init() } } +void Viewer::resetSphereColors(){ + QColor* c1 = new QColor(255, 0, 255, 255); + QColor* c2 = new QColor(0, 255, 255, 255); + QColor* c3 = new QColor(255, 255, 0, 255); + + int i = 0;/* + + QColor* colors[3] = {c1, c2, c3}; + + while(selection.hasNext()) { + Shape currentSphere = dynamic_cast(selection->getChild()); + + currentSphere->setColor(colors[i++]); + }*/ + +} + void Viewer::initShaders() { @@ -716,13 +749,44 @@ void Viewer::visit(SceneGroup &s) void Viewer::setPhong(bool on) { - m_program->bind(); - m_program->setUniformValue(m_isPhongLoc, on); - if(on) std::cout << "Phong ON\n"; - else std::cout << "Phong OFF\n"; - this->update(); + m_program->bind(); + m_program->setUniformValue(m_isPhongLoc, on); + if(on) std::cout << "Phong ON\n"; + else std::cout << "Phong OFF\n"; + this->update(); } +void Viewer::setMagLinear(bool on) { + m_program->bind(); + if(on) { + std::cout << "Linear ON" << endl; + + s_texture->setMagnificationFilter(QOpenGLTexture::Linear); + } else { + std::cout << "Nearest ON" << endl; + + s_texture->setMagnificationFilter(QOpenGLTexture::Nearest); + } + + this->update(); +} + +void Viewer::setMinLinear(bool on) { + m_program->bind(); + if(on) { + std::cout << "Linear MipMap Linear ON" << endl; + + s_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); + } else { + std::cout << "Nearest ON" << endl; + + s_texture->setMinificationFilter(QOpenGLTexture::Nearest); + } + + this->update(); +} + + void Viewer::changeColor(QColor c){ if(activeCell->getChildren()->size()){ Shape* shape = dynamic_cast (activeCell->childAt(0)); @@ -732,7 +796,7 @@ void Viewer::changeColor(QColor c){ this->update(); } -QMatrix4x4 Viewer::pickGeom(int x, int y){ +PickedGeom Viewer::pickGeom(int x, int y){ makeCurrent(); @@ -744,6 +808,7 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ isPickingActivated = true; QMap mapColorToPosition; + QMap mapColorToShape; QColor c; QRgb startColor = 1; // alpha must be 100%, glReadPixels doesn't resturn alpha unsigned char pixelData[3]; @@ -774,6 +839,7 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ //std::cout << "Setting " << startColor << " to {" << components[0] << ", " << components[0] << ", " << components[1] << ", " << components[2] << "}\n"; currentTransform.translate(components[1], -components[2], -components[0]); mapColorToPosition.insert(startColor, currentTransform); + mapColorToShape.insert(startColor, currentCube); startColor++; } } @@ -807,11 +873,17 @@ QMatrix4x4 Viewer::pickGeom(int x, int y){ //std::cout << "Picked " << pickedInt << endl; QMatrix4x4 pickedPosition = mapColorToPosition.value(pickedInt, identityMatrix); + Shape* pickedShape = mapColorToShape.value(pickedInt); mapColorToPosition.clear(); m_program->setUniformValue(m_isPickingModeLoc, false); isPickingActivated = false; - doneCurrent(); + doneCurrent(); - return pickedPosition; + PickedGeom result = PickedGeom(); + + result.position = pickedPosition; + result.shape = pickedShape; + + return result; } diff --git a/src/viewer/simpleViewer.h b/src/viewer/simpleViewer.h index fd58f40..356d3b6 100644 --- a/src/viewer/simpleViewer.h +++ b/src/viewer/simpleViewer.h @@ -37,6 +37,12 @@ QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) + +struct PickedGeom { + Shape* shape; + QMatrix4x4 position; +}; + class Viewer : public QGLViewer, protected QOpenGLFunctions_4_0_Core, public Visitor @@ -54,6 +60,8 @@ public slots: void cleanup(); void changeColor(QColor); void setPhong(bool); + void setMagLinear(bool); + void setMinLinear(bool); signals: int shapeSelected(int); @@ -71,11 +79,12 @@ protected : std::stack modelStack; private: + void resetSphereColors(); void initShaders(); void initGeometries(); void initBuffers(); void deselect(); - QMatrix4x4 pickGeom(int, int); + PickedGeom pickGeom(int, int); // shader switching variables and constants; QOpenGLShaderProgram *colorPickerShaderProgram; diff --git a/src/window/mainwindow.cpp b/src/window/mainwindow.cpp index 43621b5..e8ccf5f 100644 --- a/src/window/mainwindow.cpp +++ b/src/window/mainwindow.cpp @@ -19,6 +19,14 @@ MainWindow::MainWindow(QWidget *parent) : lightTypeGroup->addAction(ui->actionGouraud); lightTypeGroup->addAction(ui->actionPhong); + minFilterGroup = new QActionGroup(this); + minFilterGroup->addAction(ui->actionMinLin); + minFilterGroup->addAction(ui->actionMinNear); + + magFilterGroup = new QActionGroup(this); + magFilterGroup->addAction(ui->actionMagLinear); + magFilterGroup->addAction(ui->actionMagNear); + connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(onColorPickerActivate())); } @@ -35,6 +43,8 @@ void MainWindow::addViewer(Viewer* viewer) // actionGouraud shouldn't need one, since they are mutual connect(ui->actionPhong, SIGNAL(toggled(bool)), viewer, SLOT(setPhong(bool))); + connect(ui->actionMagLinear, SIGNAL(toggled(bool)), viewer, SLOT(setMagLinear(bool))); + connect(ui->actionMinLin, SIGNAL(toggled(bool)), viewer, SLOT(setMinLinear(bool))); } void MainWindow::onColorPickerActivate(){ diff --git a/src/window/mainwindow.h b/src/window/mainwindow.h index 94c2cfd..8294784 100644 --- a/src/window/mainwindow.h +++ b/src/window/mainwindow.h @@ -26,8 +26,10 @@ public slots: private: Ui::MainWindow *ui; - QColorDialog *colordialog; + QColorDialog *colordialog; QActionGroup *lightTypeGroup; + QActionGroup *minFilterGroup; + QActionGroup *magFilterGroup; }; #endif // MAINWINDOW_H