diff --git a/camera.cpp b/camera.cpp index 53b6f97..683e908 100644 --- a/camera.cpp +++ b/camera.cpp @@ -38,6 +38,12 @@ void Camera::translate(glm::vec3 vector) m_position += vector; } +void Camera::relativeTranslate(glm::vec3 vector) +{ + m_viewHasChanged = true; + m_position += vector * glm::mat3(m_viewMatrix); +} + void Camera::rotate(glm::vec2 rad_vector) { m_viewHasChanged = true; @@ -81,6 +87,7 @@ void Camera::moveTo(glm::vec3 position) void Camera::lookAt(glm::vec3 position) { + // TODO : fix this method m_viewHasChanged = true; glm::vec3 delta = position - m_position; glm::normalize(delta); @@ -107,3 +114,13 @@ glm::mat4 Camera::getViewMatrix() computeViewMatrix(); return m_viewMatrix; } + +glm::vec2 Camera::getRotation() +{ + return m_rotation; +} + +glm::vec3 Camera::getPosition() +{ + return m_position; +} diff --git a/camera.h b/camera.h index 3f4da85..0be22fa 100644 --- a/camera.h +++ b/camera.h @@ -28,6 +28,7 @@ public: // setters // relative: void translate(glm::vec3 vector); + void relativeTranslate(glm::vec3 vector); void rotate(glm::vec2 rad_vector); // absolute: void zoom(float new_fov_y); @@ -41,6 +42,9 @@ public: // getters glm::mat4 getProjectionMatrix(); glm::mat4 getViewMatrix(); + + glm::vec2 getRotation(); + glm::vec3 getPosition(); }; #endif // CAMERA_H diff --git a/entity.cpp b/entity.cpp index bcb99ce..3b22569 100644 --- a/entity.cpp +++ b/entity.cpp @@ -8,10 +8,12 @@ void Entity::draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix) { glm::mat4 modelViewMatrix = viewMatrix * modelMatrix; glm::mat4 mvp = projectionMatrix * modelViewMatrix; + glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); mat->bindAttributes(); Shader* shader = mat->getShader(); shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix); shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix); + shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix); shader->bindMatrix(shader->getLocation("MVP"), mvp); mesh->draw(); } @@ -20,3 +22,8 @@ Shader* Entity::getShader() { return mat->getShader(); } + +Material* Entity::getMaterial() +{ + return mat; +} diff --git a/entity.h b/entity.h index b975676..3f00e1c 100644 --- a/entity.h +++ b/entity.h @@ -18,6 +18,7 @@ public: Entity(Entity* myParent, Mesh* myMesh, Material* myMat) : parent(myParent), mesh(myMesh), mat(myMat) {} virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix); Shader* getShader(); + Material* getMaterial(); }; #endif // ENTITY_H diff --git a/focuscontroller.cpp b/focuscontroller.cpp new file mode 100644 index 0000000..27c983c --- /dev/null +++ b/focuscontroller.cpp @@ -0,0 +1,50 @@ +#include "focuscontroller.h" +#include "camera.h" +#include + +void FocusController::setFocus(glm::vec3* object) +{ + track = object; + dist = glm::distance2(*track, camera->getPosition()); +} + +void FocusController::mouseMove(int dx, int dy) +{ + bool needUpdate = false; + + if(dist < 0) + dist = glm::distance2(*track, camera->getPosition()); + + if(grabbed & 1) + { + camera->rotate(glm::vec2(dx*0.01f, dy*0.01f)); + needUpdate = true; + } + + if(grabbed & 4) + { + dist += dy*0.02f; + needUpdate = true; + } + + if(needUpdate) + updateCamera(); +} + +void FocusController::mouseWheelEvent(int scrollCount) +{ + if(dist < 0) + dist = glm::distance2(*track, camera->getPosition()); + + dist += scrollCount/600.0f; + updateCamera(); +} + +void FocusController::updateCamera() +{ + glm::vec2 rot = camera->getRotation(); + glm::vec3 pos = glm::vec3(std::sin(-rot.x)*std::cos(rot.y), + std::sin(rot.y), + std::cos(-rot.x)*std::cos(rot.y)); + camera->moveTo(*track + dist*pos); +} diff --git a/focuscontroller.h b/focuscontroller.h new file mode 100644 index 0000000..ce1432f --- /dev/null +++ b/focuscontroller.h @@ -0,0 +1,23 @@ +#ifndef FOCUSCONTROLLER_H +#define FOCUSCONTROLLER_H + +#include "scenecontroller.h" +#include + +class FocusController : public SceneController +{ + glm::vec3* track; + float dist; + + void updateCamera(); + +public: + FocusController(glm::vec3* object) : track(object), dist(-1) {} + + void setFocus(glm::vec3* object); + + virtual void mouseMove(int dx, int dy); + virtual void mouseWheelEvent(int scrollCount); +}; + +#endif // FOCUSCONTROLLER_H diff --git a/lights.cpp b/lights.cpp index d4455ce..c7d004e 100644 --- a/lights.cpp +++ b/lights.cpp @@ -3,12 +3,17 @@ void Lights::addLight(const glm::vec3 &myPosition, const glm::vec3 myColor) { - Light l; - l.position = myPosition; - l.color = myColor; + if(lights.size() < MAX_LIGHTS) + { + Light l; + l.position = myPosition; + l.color = myColor; + lights.push_back(l); + } } void Lights::bind(GLuint location, Shader* shader) { - //shader->bindVec3Array(location, (glm::vec3*)lights.data(), lights.size()*2); + if(lights.size() > 0) + shader->bindVec3Array(location, (glm::vec3*)lights.data(), lights.size()*2); } diff --git a/lights.h b/lights.h index 0db31b4..cd266c8 100644 --- a/lights.h +++ b/lights.h @@ -5,6 +5,8 @@ #include #include +#define MAX_LIGHTS 16 + class Shader; class Lights diff --git a/mainwindow.ui b/mainwindow.ui index 27185b2..c8d03fd 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 483 - 369 + 757 + 492 @@ -40,45 +40,11 @@ 0 0 - 483 - 20 + 757 + 21 - - - false - - - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - renderer - - - - - - diff --git a/material.h b/material.h index f4fd630..7aea868 100644 --- a/material.h +++ b/material.h @@ -10,7 +10,8 @@ public: Material(Shader* myShader) : shader(myShader) {} Shader* getShader() {return shader;} - virtual void bindAttributes() = 0; + virtual void bindAttributes() = 0; + virtual bool requireLights() {return true;} protected: Shader* shader; diff --git a/myglwidget.cpp b/myglwidget.cpp index 6f6edbc..f192864 100644 --- a/myglwidget.cpp +++ b/myglwidget.cpp @@ -9,6 +9,7 @@ #include "utils.h" #include "texture.h" #include "sparrowrenderer.h" +#include "focuscontroller.h" #include #include #include @@ -16,13 +17,16 @@ MyGLWidget::MyGLWidget(QWidget *parent) : QGLWidget(parent), - renderer(NULL) + renderer(NULL), + controller(NULL) {} MyGLWidget::~MyGLWidget() { if(renderer != NULL) delete(renderer); + if(controller != NULL) + delete(controller); } Scene* MyGLWidget::buildScene() @@ -48,12 +52,14 @@ Scene* MyGLWidget::buildScene() std::string vertSource = Utils::fileToString("../phong.vert"); std::string fragSource = Utils::fileToString("../phong.frag"); Shader* shader = new Shader(vertSource, fragSource); - PhongMaterial* mat = new PhongMaterial(shader); + PhongMaterial* mat = new PhongMaterial(shader, glm::vec3(1), glm::vec3(1), 20.0f); Texture* tex = new Texture("../data/noise.png"); mat->setTexture(tex); scene->addEntity(myGrid, mat); + scene->addDirectionnalLight(glm::vec3(2, 3, 4), glm::vec3(0.6f, 0.5f, 0.4f)); + return scene; } @@ -62,8 +68,9 @@ void MyGLWidget::initializeGL() makeCurrent(); renderer = new SparrowRenderer(width(), height()); Scene* scene = buildScene(); + controller = new FocusController(new glm::vec3(0)); renderer->setScene(scene); - controller.setScene(scene); + controller->setScene(scene); } void MyGLWidget::resizeGL(int width, int height) @@ -79,30 +86,36 @@ void MyGLWidget::paintGL() void MyGLWidget::mouseMoveEvent(QMouseEvent *e) { - controller.mouseMove(e->pos().x() - last.x(), e->pos().y() - last.y()); + controller->mouseMove(e->pos().x() - last.x(), e->pos().y() - last.y()); last = e->pos(); updateGL(); } void MyGLWidget::mousePressEvent(QMouseEvent* e) { - controller.mouseEvent(e->button(), true); + controller->mouseEvent(e->button(), true); last = e->pos(); updateGL(); } void MyGLWidget::mouseReleaseEvent(QMouseEvent* e) { - controller.mouseEvent(e->button(), false); + controller->mouseEvent(e->button(), false); + updateGL(); +} + +void MyGLWidget::wheelEvent(QWheelEvent *e) +{ + controller->mouseWheelEvent(e->delta()); updateGL(); } void MyGLWidget::keyPressEvent(QKeyEvent *e) { - controller.mouseEvent(e->key(), true); + controller->mouseEvent(e->key(), true); updateGL(); } void MyGLWidget::keyReleaseEvent(QKeyEvent *e) { - controller.mouseEvent(e->key(), false); + controller->mouseEvent(e->key(), false); updateGL(); } diff --git a/myglwidget.h b/myglwidget.h index cfe2afc..a0c1491 100644 --- a/myglwidget.h +++ b/myglwidget.h @@ -1,11 +1,11 @@ #ifndef MYGLWIDGET_H #define MYGLWIDGET_H -#include "scenecontroller.h" #include class Scene; class SparrowRenderer; +class SceneController; namespace Ui { class MyGLWidget; @@ -16,7 +16,7 @@ class MyGLWidget : public QGLWidget Q_OBJECT SparrowRenderer* renderer; - SceneController controller; + SceneController* controller; QPoint last; public: @@ -34,6 +34,7 @@ private: void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e); + void wheelEvent(QWheelEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); }; diff --git a/phong.frag b/phong.frag index def8f16..f4c1ce3 100644 --- a/phong.frag +++ b/phong.frag @@ -5,6 +5,9 @@ uniform vec3 materialKd; uniform vec3 materialKs; uniform float materialNs; +uniform vec3 dirLights[32]; +uniform vec3 pointLights[32]; + // texture uniform sampler2D baseTexture; @@ -12,6 +15,9 @@ uniform sampler2D baseTexture; in vec3 varNormal; in vec2 varTexCoord; +in vec3 lightDirInView[16]; +in vec3 halfVecInView[16]; + // resultat layout(location = 0)out vec4 outColor; @@ -31,7 +37,8 @@ vec3 computeLight(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 no void main(void) { vec3 kd = vec3(texture2D(baseTexture, varTexCoord)); + vec3 light = 0.1f*kd + computeLight(kd, materialKs, materialNs, dirLights[1], varNormal, lightDirInView[0], halfVecInView[0]); - outColor = vec4(kd, 1); + outColor = vec4(light, 1); } diff --git a/phong.vert b/phong.vert index f8e9f86..5d71eea 100644 --- a/phong.vert +++ b/phong.vert @@ -6,20 +6,28 @@ uniform mat4 MVP; uniform mat4 normalMatrix; uniform mat4 viewMatrix; +uniform vec3 dirLights[32]; +uniform vec3 pointLights[32]; + layout(location = 0)in vec3 inPosition; layout(location = 1)in vec3 inNormal; layout(location = 2)in vec4 inTexCoord; +out vec3 lightDirInView[16]; +out vec3 halfVecInView[16]; + out vec3 varNormal; out vec2 varTexCoord; -/*void computeLightingVectorsInView(in vec3 posInView, in vec3 lightPosition, out vec3 lightDir, out vec3 halfVec){ +void computeLightingVectorsInView(in vec3 posInView, in vec3 lightPosition, out vec3 lightDir, out vec3 halfVec){ lightDir = vec3(viewMatrix*vec4(lightPosition, 1.0)) - posInView; halfVec = normalize(lightDir - posInView); lightDir = normalize(lightDir); -}*/ +} void main(void) { + computeLightingVectorsInView(vec3(modelViewMatrix*vec4(inPosition, 1.0)), dirLights[0], lightDirInView[0], halfVecInView[0]); + // normales corrigees (en fonction de la vue) varNormal = normalize(vec3(normalMatrix*vec4(inNormal,0))); diff --git a/scene.cpp b/scene.cpp index 2a620d3..2831c86 100644 --- a/scene.cpp +++ b/scene.cpp @@ -5,6 +5,7 @@ #include "camera.h" #include "entity.h" #include "shader.h" +#include "material.h" // MAIN METHODS @@ -22,8 +23,11 @@ void Scene::drawAll() { Shader* shader = e->getShader(); shader->bind(); - directionnalLights.bind(shader->getLocation("dirLights"), shader); - pointLights.bind(shader->getLocation("pointLights"), shader); + if(e->getMaterial()->requireLights()) + { + directionnalLights.bind(shader->getLocation("dirLights"), shader); + pointLights.bind(shader->getLocation("pointLights"), shader); + } e->draw(viewMatrix, projectionMatrix); } } diff --git a/scenecontroller.cpp b/scenecontroller.cpp index 8b659a2..78ef202 100644 --- a/scenecontroller.cpp +++ b/scenecontroller.cpp @@ -9,22 +9,6 @@ void SceneController::setScene(Scene* myScene) camera = scene->getCamera(); } -void SceneController::mouseMove(int dx, int dy) -{ - switch(grabbed) - { - case 1: - camera->rotate(glm::vec2(dx*3.14f/180, dy*3.14f/180)); - break; - case 2: - camera->translate(glm::vec3(dx*0.01f, dy*0.01f, 0)); - //camera->lookAt(glm::vec3(0, 0, 0)); - break; - default: - break; - } -} - void SceneController::mouseEvent(int button, bool state) { switch (button) { @@ -34,12 +18,11 @@ void SceneController::mouseEvent(int button, bool state) case Qt::RightButton: grabbed += state ? 2 : -2; break; + case Qt::MiddleButton: + grabbed += state ? 4 : -4; + break; default: break; } } -void SceneController::keyEvent(int key, bool state) -{ - -} diff --git a/scenecontroller.h b/scenecontroller.h index 6916869..fe025ff 100644 --- a/scenecontroller.h +++ b/scenecontroller.h @@ -16,9 +16,10 @@ public: SceneController() : camera(NULL), scene(NULL), grabbed(0) {} void setScene(Scene* myScene); - virtual void mouseMove(int dx, int dy); + virtual void mouseMove(int dx, int dy) {} virtual void mouseEvent(int button, bool state); - virtual void keyEvent(int key, bool state); + virtual void keyEvent(int key, bool state) {} + virtual void mouseWheelEvent(int scrollCount) {} }; #endif // SCENECONTROLLER_H diff --git a/shader.cpp b/shader.cpp index 94324c2..9acb2ff 100644 --- a/shader.cpp +++ b/shader.cpp @@ -127,6 +127,11 @@ void Shader::bindVec3(GLuint location, glm::vec3 vec) glAssert(glUniform3fv(location, 1, glm::value_ptr(vec))); } +void Shader::bindVec3Array(GLuint location, glm::vec3* vec, int nb_elements) +{ + glAssert(glUniform3fv(location, nb_elements, (GLfloat*)vec)); +} + void Shader::bindTexture(GLuint location, GLuint tex_id) { glAssert(glUniform1i(location, tex_id)); diff --git a/skyboxmaterial.cpp b/skyboxmaterial.cpp index 1ca4fa1..e0ae6a8 100644 --- a/skyboxmaterial.cpp +++ b/skyboxmaterial.cpp @@ -10,3 +10,8 @@ void SkyBoxMaterial::bindAttributes() { skyboxTex->bind(0); } + +bool SkyBoxMaterial::requireLights() +{ + return false; +} diff --git a/skyboxmaterial.h b/skyboxmaterial.h index aae6b23..753f0de 100644 --- a/skyboxmaterial.h +++ b/skyboxmaterial.h @@ -10,6 +10,7 @@ class SkyBoxMaterial : public Material public: SkyBoxMaterial(Shader* myShader, const std::string filenames[6]); virtual void bindAttributes(); + virtual bool requireLights(); private: Texture* skyboxTex; diff --git a/sparrowRenderer.pro b/sparrowRenderer.pro index d6217d4..7d67d74 100644 --- a/sparrowRenderer.pro +++ b/sparrowRenderer.pro @@ -37,7 +37,8 @@ SOURCES += main.cpp\ utils.cpp \ lights.cpp \ sparrowrenderer.cpp \ - resourcebase.cpp + resourcebase.cpp \ + focuscontroller.cpp HEADERS += mainwindow.h \ myglwidget.h \ @@ -58,7 +59,8 @@ HEADERS += mainwindow.h \ utils.h \ lights.h \ sparrowrenderer.h \ - resourcebase.h + resourcebase.h \ + focuscontroller.h FORMS += mainwindow.ui