lights and blinn-phong are working well, and i also added a focusController, which allows to navigate freely around a target

This commit is contained in:
Anselme 2015-07-01 20:56:32 +02:00
parent eaa70e2cde
commit 3678b8d392
21 changed files with 188 additions and 82 deletions

View File

@ -38,6 +38,12 @@ void Camera::translate(glm::vec3 vector)
m_position += 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) void Camera::rotate(glm::vec2 rad_vector)
{ {
m_viewHasChanged = true; m_viewHasChanged = true;
@ -81,6 +87,7 @@ void Camera::moveTo(glm::vec3 position)
void Camera::lookAt(glm::vec3 position) void Camera::lookAt(glm::vec3 position)
{ {
// TODO : fix this method
m_viewHasChanged = true; m_viewHasChanged = true;
glm::vec3 delta = position - m_position; glm::vec3 delta = position - m_position;
glm::normalize(delta); glm::normalize(delta);
@ -107,3 +114,13 @@ glm::mat4 Camera::getViewMatrix()
computeViewMatrix(); computeViewMatrix();
return m_viewMatrix; return m_viewMatrix;
} }
glm::vec2 Camera::getRotation()
{
return m_rotation;
}
glm::vec3 Camera::getPosition()
{
return m_position;
}

View File

@ -28,6 +28,7 @@ public:
// setters // setters
// relative: // relative:
void translate(glm::vec3 vector); void translate(glm::vec3 vector);
void relativeTranslate(glm::vec3 vector);
void rotate(glm::vec2 rad_vector); void rotate(glm::vec2 rad_vector);
// absolute: // absolute:
void zoom(float new_fov_y); void zoom(float new_fov_y);
@ -41,6 +42,9 @@ public:
// getters // getters
glm::mat4 getProjectionMatrix(); glm::mat4 getProjectionMatrix();
glm::mat4 getViewMatrix(); glm::mat4 getViewMatrix();
glm::vec2 getRotation();
glm::vec3 getPosition();
}; };
#endif // CAMERA_H #endif // CAMERA_H

View File

@ -8,10 +8,12 @@ void Entity::draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix)
{ {
glm::mat4 modelViewMatrix = viewMatrix * modelMatrix; glm::mat4 modelViewMatrix = viewMatrix * modelMatrix;
glm::mat4 mvp = projectionMatrix * modelViewMatrix; glm::mat4 mvp = projectionMatrix * modelViewMatrix;
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
mat->bindAttributes(); mat->bindAttributes();
Shader* shader = mat->getShader(); Shader* shader = mat->getShader();
shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix); shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix);
shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix); shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix);
shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix);
shader->bindMatrix(shader->getLocation("MVP"), mvp); shader->bindMatrix(shader->getLocation("MVP"), mvp);
mesh->draw(); mesh->draw();
} }
@ -20,3 +22,8 @@ Shader* Entity::getShader()
{ {
return mat->getShader(); return mat->getShader();
} }
Material* Entity::getMaterial()
{
return mat;
}

View File

@ -18,6 +18,7 @@ public:
Entity(Entity* myParent, Mesh* myMesh, Material* myMat) : parent(myParent), mesh(myMesh), mat(myMat) {} Entity(Entity* myParent, Mesh* myMesh, Material* myMat) : parent(myParent), mesh(myMesh), mat(myMat) {}
virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix); virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix);
Shader* getShader(); Shader* getShader();
Material* getMaterial();
}; };
#endif // ENTITY_H #endif // ENTITY_H

50
focuscontroller.cpp Normal file
View File

@ -0,0 +1,50 @@
#include "focuscontroller.h"
#include "camera.h"
#include <glm/ext.hpp>
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);
}

23
focuscontroller.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef FOCUSCONTROLLER_H
#define FOCUSCONTROLLER_H
#include "scenecontroller.h"
#include <glm/fwd.hpp>
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

View File

@ -3,12 +3,17 @@
void Lights::addLight(const glm::vec3 &myPosition, const glm::vec3 myColor) void Lights::addLight(const glm::vec3 &myPosition, const glm::vec3 myColor)
{ {
Light l; if(lights.size() < MAX_LIGHTS)
l.position = myPosition; {
l.color = myColor; Light l;
l.position = myPosition;
l.color = myColor;
lights.push_back(l);
}
} }
void Lights::bind(GLuint location, Shader* shader) 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);
} }

View File

@ -5,6 +5,8 @@
#include <glew/glew.h> #include <glew/glew.h>
#include <vector> #include <vector>
#define MAX_LIGHTS 16
class Shader; class Shader;
class Lights class Lights

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>483</width> <width>757</width>
<height>369</height> <height>492</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -40,45 +40,11 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>483</width> <width>757</width>
<height>20</height> <height>21</height>
</rect> </rect>
</property> </property>
</widget> </widget>
<widget class="QDockWidget" name="dockWidget_4">
<property name="floating">
<bool>false</bool>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>renderer</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

View File

@ -10,7 +10,8 @@ public:
Material(Shader* myShader) : shader(myShader) {} Material(Shader* myShader) : shader(myShader) {}
Shader* getShader() {return shader;} Shader* getShader() {return shader;}
virtual void bindAttributes() = 0; virtual void bindAttributes() = 0;
virtual bool requireLights() {return true;}
protected: protected:
Shader* shader; Shader* shader;

View File

@ -9,6 +9,7 @@
#include "utils.h" #include "utils.h"
#include "texture.h" #include "texture.h"
#include "sparrowrenderer.h" #include "sparrowrenderer.h"
#include "focuscontroller.h"
#include <iostream> #include <iostream>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <QKeyEvent> #include <QKeyEvent>
@ -16,13 +17,16 @@
MyGLWidget::MyGLWidget(QWidget *parent) : MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent), QGLWidget(parent),
renderer(NULL) renderer(NULL),
controller(NULL)
{} {}
MyGLWidget::~MyGLWidget() MyGLWidget::~MyGLWidget()
{ {
if(renderer != NULL) if(renderer != NULL)
delete(renderer); delete(renderer);
if(controller != NULL)
delete(controller);
} }
Scene* MyGLWidget::buildScene() Scene* MyGLWidget::buildScene()
@ -48,12 +52,14 @@ Scene* MyGLWidget::buildScene()
std::string vertSource = Utils::fileToString("../phong.vert"); std::string vertSource = Utils::fileToString("../phong.vert");
std::string fragSource = Utils::fileToString("../phong.frag"); std::string fragSource = Utils::fileToString("../phong.frag");
Shader* shader = new Shader(vertSource, fragSource); 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"); Texture* tex = new Texture("../data/noise.png");
mat->setTexture(tex); mat->setTexture(tex);
scene->addEntity(myGrid, mat); scene->addEntity(myGrid, mat);
scene->addDirectionnalLight(glm::vec3(2, 3, 4), glm::vec3(0.6f, 0.5f, 0.4f));
return scene; return scene;
} }
@ -62,8 +68,9 @@ void MyGLWidget::initializeGL()
makeCurrent(); makeCurrent();
renderer = new SparrowRenderer(width(), height()); renderer = new SparrowRenderer(width(), height());
Scene* scene = buildScene(); Scene* scene = buildScene();
controller = new FocusController(new glm::vec3(0));
renderer->setScene(scene); renderer->setScene(scene);
controller.setScene(scene); controller->setScene(scene);
} }
void MyGLWidget::resizeGL(int width, int height) void MyGLWidget::resizeGL(int width, int height)
@ -79,30 +86,36 @@ void MyGLWidget::paintGL()
void MyGLWidget::mouseMoveEvent(QMouseEvent *e) 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(); last = e->pos();
updateGL(); updateGL();
} }
void MyGLWidget::mousePressEvent(QMouseEvent* e) void MyGLWidget::mousePressEvent(QMouseEvent* e)
{ {
controller.mouseEvent(e->button(), true); controller->mouseEvent(e->button(), true);
last = e->pos(); last = e->pos();
updateGL(); updateGL();
} }
void MyGLWidget::mouseReleaseEvent(QMouseEvent* e) 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(); updateGL();
} }
void MyGLWidget::keyPressEvent(QKeyEvent *e) void MyGLWidget::keyPressEvent(QKeyEvent *e)
{ {
controller.mouseEvent(e->key(), true); controller->mouseEvent(e->key(), true);
updateGL(); updateGL();
} }
void MyGLWidget::keyReleaseEvent(QKeyEvent *e) void MyGLWidget::keyReleaseEvent(QKeyEvent *e)
{ {
controller.mouseEvent(e->key(), false); controller->mouseEvent(e->key(), false);
updateGL(); updateGL();
} }

View File

@ -1,11 +1,11 @@
#ifndef MYGLWIDGET_H #ifndef MYGLWIDGET_H
#define MYGLWIDGET_H #define MYGLWIDGET_H
#include "scenecontroller.h"
#include <QGLWidget> #include <QGLWidget>
class Scene; class Scene;
class SparrowRenderer; class SparrowRenderer;
class SceneController;
namespace Ui { namespace Ui {
class MyGLWidget; class MyGLWidget;
@ -16,7 +16,7 @@ class MyGLWidget : public QGLWidget
Q_OBJECT Q_OBJECT
SparrowRenderer* renderer; SparrowRenderer* renderer;
SceneController controller; SceneController* controller;
QPoint last; QPoint last;
public: public:
@ -34,6 +34,7 @@ private:
void mouseMoveEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent* e); void mousePressEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e);
void wheelEvent(QWheelEvent *e);
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e);
}; };

View File

@ -5,6 +5,9 @@ uniform vec3 materialKd;
uniform vec3 materialKs; uniform vec3 materialKs;
uniform float materialNs; uniform float materialNs;
uniform vec3 dirLights[32];
uniform vec3 pointLights[32];
// texture // texture
uniform sampler2D baseTexture; uniform sampler2D baseTexture;
@ -12,6 +15,9 @@ uniform sampler2D baseTexture;
in vec3 varNormal; in vec3 varNormal;
in vec2 varTexCoord; in vec2 varTexCoord;
in vec3 lightDirInView[16];
in vec3 halfVecInView[16];
// resultat // resultat
layout(location = 0)out vec4 outColor; 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) { void main(void) {
vec3 kd = vec3(texture2D(baseTexture, varTexCoord)); 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);
} }

View File

@ -6,20 +6,28 @@ uniform mat4 MVP;
uniform mat4 normalMatrix; uniform mat4 normalMatrix;
uniform mat4 viewMatrix; uniform mat4 viewMatrix;
uniform vec3 dirLights[32];
uniform vec3 pointLights[32];
layout(location = 0)in vec3 inPosition; layout(location = 0)in vec3 inPosition;
layout(location = 1)in vec3 inNormal; layout(location = 1)in vec3 inNormal;
layout(location = 2)in vec4 inTexCoord; layout(location = 2)in vec4 inTexCoord;
out vec3 lightDirInView[16];
out vec3 halfVecInView[16];
out vec3 varNormal; out vec3 varNormal;
out vec2 varTexCoord; 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; lightDir = vec3(viewMatrix*vec4(lightPosition, 1.0)) - posInView;
halfVec = normalize(lightDir - posInView); halfVec = normalize(lightDir - posInView);
lightDir = normalize(lightDir); lightDir = normalize(lightDir);
}*/ }
void main(void) { void main(void) {
computeLightingVectorsInView(vec3(modelViewMatrix*vec4(inPosition, 1.0)), dirLights[0], lightDirInView[0], halfVecInView[0]);
// normales corrigees (en fonction de la vue) // normales corrigees (en fonction de la vue)
varNormal = normalize(vec3(normalMatrix*vec4(inNormal,0))); varNormal = normalize(vec3(normalMatrix*vec4(inNormal,0)));

View File

@ -5,6 +5,7 @@
#include "camera.h" #include "camera.h"
#include "entity.h" #include "entity.h"
#include "shader.h" #include "shader.h"
#include "material.h"
// MAIN METHODS // MAIN METHODS
@ -22,8 +23,11 @@ void Scene::drawAll()
{ {
Shader* shader = e->getShader(); Shader* shader = e->getShader();
shader->bind(); shader->bind();
directionnalLights.bind(shader->getLocation("dirLights"), shader); if(e->getMaterial()->requireLights())
pointLights.bind(shader->getLocation("pointLights"), shader); {
directionnalLights.bind(shader->getLocation("dirLights"), shader);
pointLights.bind(shader->getLocation("pointLights"), shader);
}
e->draw(viewMatrix, projectionMatrix); e->draw(viewMatrix, projectionMatrix);
} }
} }

View File

@ -9,22 +9,6 @@ void SceneController::setScene(Scene* myScene)
camera = scene->getCamera(); 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) void SceneController::mouseEvent(int button, bool state)
{ {
switch (button) { switch (button) {
@ -34,12 +18,11 @@ void SceneController::mouseEvent(int button, bool state)
case Qt::RightButton: case Qt::RightButton:
grabbed += state ? 2 : -2; grabbed += state ? 2 : -2;
break; break;
case Qt::MiddleButton:
grabbed += state ? 4 : -4;
break;
default: default:
break; break;
} }
} }
void SceneController::keyEvent(int key, bool state)
{
}

View File

@ -16,9 +16,10 @@ public:
SceneController() : camera(NULL), scene(NULL), grabbed(0) {} SceneController() : camera(NULL), scene(NULL), grabbed(0) {}
void setScene(Scene* myScene); 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 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 #endif // SCENECONTROLLER_H

View File

@ -127,6 +127,11 @@ void Shader::bindVec3(GLuint location, glm::vec3 vec)
glAssert(glUniform3fv(location, 1, glm::value_ptr(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) void Shader::bindTexture(GLuint location, GLuint tex_id)
{ {
glAssert(glUniform1i(location, tex_id)); glAssert(glUniform1i(location, tex_id));

View File

@ -10,3 +10,8 @@ void SkyBoxMaterial::bindAttributes()
{ {
skyboxTex->bind(0); skyboxTex->bind(0);
} }
bool SkyBoxMaterial::requireLights()
{
return false;
}

View File

@ -10,6 +10,7 @@ class SkyBoxMaterial : public Material
public: public:
SkyBoxMaterial(Shader* myShader, const std::string filenames[6]); SkyBoxMaterial(Shader* myShader, const std::string filenames[6]);
virtual void bindAttributes(); virtual void bindAttributes();
virtual bool requireLights();
private: private:
Texture* skyboxTex; Texture* skyboxTex;

View File

@ -37,7 +37,8 @@ SOURCES += main.cpp\
utils.cpp \ utils.cpp \
lights.cpp \ lights.cpp \
sparrowrenderer.cpp \ sparrowrenderer.cpp \
resourcebase.cpp resourcebase.cpp \
focuscontroller.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
myglwidget.h \ myglwidget.h \
@ -58,7 +59,8 @@ HEADERS += mainwindow.h \
utils.h \ utils.h \
lights.h \ lights.h \
sparrowrenderer.h \ sparrowrenderer.h \
resourcebase.h resourcebase.h \
focuscontroller.h
FORMS += mainwindow.ui FORMS += mainwindow.ui