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;
}
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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

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)
{
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);
}

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>483</width>
<height>369</height>
<width>757</width>
<height>492</height>
</rect>
</property>
<property name="windowTitle">
@ -40,45 +40,11 @@
<rect>
<x>0</x>
<y>0</y>
<width>483</width>
<height>20</height>
<width>757</width>
<height>21</height>
</rect>
</property>
</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>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -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;

View File

@ -9,6 +9,7 @@
#include "utils.h"
#include "texture.h"
#include "sparrowrenderer.h"
#include "focuscontroller.h"
#include <iostream>
#include <glm/glm.hpp>
#include <QKeyEvent>
@ -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();
}

View File

@ -1,11 +1,11 @@
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include "scenecontroller.h"
#include <QGLWidget>
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);
};

View File

@ -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);
}

View File

@ -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)));

View File

@ -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);
}
}

View File

@ -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)
{
}

View File

@ -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

View File

@ -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));

View File

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

View File

@ -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;

View File

@ -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