initial commit

This commit is contained in:
Anselme 2015-06-22 01:57:02 +02:00
commit 1dce5a251d
23 changed files with 826 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/*
*.user

112
camera.cpp Normal file
View File

@ -0,0 +1,112 @@
#include "camera.h"
#include <glm/ext.hpp>
#include <cmath>
#define _USE_MATH_DEFINES
Camera::Camera(int width, int height, float fov_y, float near, float far, glm::vec3 pos) :
m_projectionHasChanged(true),
m_viewHasChanged(true),
m_fov(fov_y),
m_width(width),
m_height(height),
m_near(near),
m_far(far),
m_position(pos),
m_rotation(glm::vec2())
{
computeProjectionMatrix();
computeViewMatrix();
}
void Camera::computeProjectionMatrix()
{
m_projectionMatrix = glm::perspectiveFov(m_fov, (float)m_width, (float)m_height, m_near, m_far);
m_projectionHasChanged = false;
}
void Camera::computeViewMatrix()
{
m_viewMatrix = glm::rotate(glm::mat4(), m_rotation.y, glm::vec3(0, 1, 0));
m_viewMatrix = glm::rotate(m_viewMatrix, m_rotation.x, glm::vec3(1, 0, 0));
m_viewMatrix = glm::translate(m_viewMatrix, -m_position);
m_viewHasChanged = false;
}
void Camera::translate(glm::vec3 vector)
{
m_viewHasChanged = true;
m_position += vector;
}
void Camera::rotate(glm::vec2 rad_vector)
{
m_viewHasChanged = true;
m_rotation += rad_vector;
if(m_rotation.y > M_PI/2)
m_rotation.y = M_PI/2;
if(m_rotation.y < -M_PI/2)
m_rotation.y = -M_PI/2;
}
void Camera::zoom(float new_fov_y)
{
m_projectionHasChanged = true;
m_fov = new_fov_y;
}
void Camera::resize(int width, int height)
{
m_projectionHasChanged = true;
m_width = width;
m_height = height;
}
void Camera::setNear(float near)
{
m_projectionHasChanged = true;
m_near = near;
}
void Camera::setFar(float far)
{
m_projectionHasChanged = true;
m_far = far;
}
void Camera::moveTo(glm::vec3 position)
{
m_viewHasChanged = true;
m_position = position;
}
void Camera::lookAt(glm::vec3 position)
{
m_viewHasChanged = true;
glm::vec3 delta = position - m_position;
glm::normalize(delta);
m_rotation.y = std::asin(delta.y);
m_rotation.x = std::acos(delta.z/std::acos(delta.y));
if(delta.z < 0) m_rotation.x += M_PI;
}
void Camera::lookAt(glm::vec2 rotation)
{
m_viewHasChanged = true;
m_rotation = rotation;
}
glm::mat4 Camera::getProjectionMatrix()
{
if(m_projectionHasChanged)
computeProjectionMatrix();
return m_projectionMatrix;
}
glm::mat4 Camera::getViewMatrix()
{
if(m_viewHasChanged)
computeViewMatrix();
return m_viewMatrix;
}

46
camera.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef CAMERA_H
#define CAMERA_H
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
class Camera
{
bool m_projectionHasChanged;
bool m_viewHasChanged;
glm::mat4 m_projectionMatrix;
glm::mat4 m_viewMatrix;
float m_fov;
int m_width;
int m_height;
float m_near;
float m_far;
glm::vec3 m_position;
glm::vec2 m_rotation;
void computeProjectionMatrix();
void computeViewMatrix();
public:
//constructor
Camera(int width = 800, int height = 600, float fov_y = 45, float near = 0.1f, float far = 20, glm::vec3 pos = glm::vec3());
// setters
// relative:
void translate(glm::vec3 vector);
void rotate(glm::vec2 rad_vector);
// absolute:
void zoom(float new_fov_y);
void resize(int width, int height);
void setNear(float near);
void setFar(float far);
void moveTo(glm::vec3 position);
void lookAt(glm::vec3 position);
void lookAt(glm::vec2 rotation);
// getters
glm::mat4 getProjectionMatrix();
glm::mat4 getViewMatrix();
};
#endif // CAMERA_H

24
glassert.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef GLASSERT
#define GLASSERT
/**
*
* OpenGL error management class.
*
*/
#include <iostream>
#include <cassert>
#define STR(x) #x
#define glAssert(code) \
code; \
{\
GLuint err = glGetError(); \
if (err != GL_NO_ERROR) { \
std::cerr<<"erreur OpenGL ("<<__FILE__<<":"<<__LINE__<<", "<<STR(code)<<") : "<<(const char*)gluErrorString (err)<<"("<<err<<")"<<std::endl; \
} \
}
#endif // GLASSERT

11
main.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

14
mainwindow.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}

22
mainwindow.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

59
mainwindow.ui Normal file
View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>483</width>
<height>369</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<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="MyGLWidget" name="openGLWidget"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>483</width>
<height>20</height>
</rect>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyGLWidget</class>
<extends>QOpenGLWidget</extends>
<header>myglwidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

12
material.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "material.h"
Material::Material()
{
}
Material::~Material()
{
}

12
material.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef MATERIAL_H
#define MATERIAL_H
class Material
{
public:
Material();
~Material();
};
#endif // MATERIAL_H

23
mesh.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "mesh.h"
Mesh::Mesh()
{
}
void Mesh::addVertex(Vertex& v)
{
vertices.push_back(v);
}
void Mesh::addFace(int i1, int i2, int i3)
{
indices.push_back(i1);
indices.push_back(i2);
indices.push_back(i3);
}
void Mesh::draw()
{
}

27
mesh.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef MESH_H
#define MESH_H
#include <vector>
#include <glm/glm.hpp>
class Mesh
{
public:
typedef struct
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texCoord;
} Vertex;
Mesh();
void addVertex(Vertex& v);
void addFace(int i1, int i2, int i3);
void draw();
private:
std::vector<Vertex> vertices;
std::vector<int> indices;
};
#endif // MESH_H

63
myglwidget.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <glew/glew.h>
#include "myglwidget.h"
#include "sparrowrenderer.h"
#include "glassert.h"
#include <iostream>
#include <glm/glm.hpp>
MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent),
renderer(NULL)
{
}
MyGLWidget::~MyGLWidget()
{
if(renderer != NULL)
delete(renderer);
}
void MyGLWidget::initializeGL()
{
makeCurrent();
GLenum err = glewInit(); // init and check glew
if (GLEW_OK != err)
{
std::cerr << "Warning: glewInit failed!" << std::endl;
}
if (!GLEW_ARB_vertex_program ||
!GLEW_ARB_fragment_program ||
!GLEW_ARB_texture_float ||
!GLEW_ARB_draw_buffers ||
!GLEW_ARB_framebuffer_object)
{
std::cerr << "Warning: Shaders not supported!" << std::endl;
}
std::cout << "OpenGL version " << glGetString(GL_VERSION) << std::endl;
std::cout << "GLSL version " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
std::cout.flush();
glAssert(glEnable(GL_DEPTH_TEST));
glAssert(glEnable(GL_CULL_FACE));
glAssert(glEnable(GL_TEXTURE_2D));
glAssert(glViewport(0, 0, width(), height()));
renderer = new SparrowRenderer(width(), height());
}
void MyGLWidget::resizeGL(int width, int height)
{
glAssert(glViewport(0, 0, width, height));
renderer->resize(width, height);
updateGL();
}
void MyGLWidget::paintGL()
{
glAssert(glClearColor(0.60, 0.65, 0.75, 1.0));
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
renderer->render();
}

28
myglwidget.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QGLWidget>
class SparrowRenderer;
namespace Ui {
class MyGLWidget;
}
class MyGLWidget : public QGLWidget
{
Q_OBJECT
SparrowRenderer* renderer;
public:
explicit MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
};
#endif // MYGLWIDGET_H

37
phong.frag Normal file
View File

@ -0,0 +1,37 @@
#version 330
// material
uniform vec3 materialKd;
uniform vec3 materialKs;
uniform float materialNs;
// texture
uniform sampler2D baseTexture;
// fragment
in vec3 varNormal;
in vec2 varTexCoord;
// resultat
layout(location = 0)out vec4 outColor;
// --------------------
vec3 computeLight(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec){
float diffuse = 0;
float specular = 0;
diffuse = dot(normal, lightDir);
diffuse = diffuse < 0 ? 0 : diffuse;
specular = dot(halfVec, normal);
specular = specular < 0 ? 0 : specular;
return color*diffuse*(kd+ks*pow(specular, ns));
}
void main(void) {
vec3 kd = vec3(texture2D(baseTexture, varTexCoord));
outColor = vec4(kd, 1);
}

31
phong.vert Normal file
View File

@ -0,0 +1,31 @@
#version 330
// Matrices
uniform mat4 modelViewMatrix;
uniform mat4 MVP;
uniform mat4 normalMatrix;
uniform mat4 viewMatrix;
layout(location = 0)in vec3 inPosition;
layout(location = 1)in vec3 inNormal;
layout(location = 2)in vec4 inTexCoord;
out vec3 varNormal;
out vec2 varTexCoord;
/*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) {
// normales corrigées (en fonction de la vue)
varNormal = normalize(vec3(normalMatrix*vec4(inNormal,0)));
// coordonnées de texture
varTexCoord = inTexCoord.xy;
// position du vertex
gl_Position = MVP*vec4(inPosition, 1.0);
}

47
scene.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "scene.h"
#include "glassert.h"
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include "camera.h"
Scene::Scene()
{
}
Scene::~Scene()
{
for(Entity* e : entities)
delete(e);
}
void Scene::addEntity(Mesh& mesh, Material& mat)
{
entities.push_back(new Entity(NULL, mesh, mat));
}
void Scene::addEntity(Mesh& mesh)
{
Material default_material = Material();
entities.push_back(new Entity(NULL, mesh, default_material));
}
void Scene::drawEntities(GLuint programId)
{
glm::mat4 viewMatrix = camera->getViewMatrix();
glm::mat4 projectionMatrix = camera->getProjectionMatrix();
glAssert(GLuint viewMatrixUniform = glGetUniformLocation(programId, "viewMatrix"));
glAssert(glUniformMatrix4fv(viewMatrixUniform, 1, GL_FALSE, glm::value_ptr(viewMatrix)));
for(Entity* e : entities)
e->mesh.draw();
}
void Scene::setCamera(Camera* myCamera)
{
camera = myCamera;
}
Camera* Scene::getCamera()
{
return camera;
}

39
scene.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef SCENE_H
#define SCENE_H
#include "mesh.h"
#include "material.h"
#include <glew/glew.h>
class Camera;
class Scene
{
typedef struct s_entity
{
Material mat;
Mesh mesh;
s_entity* parent;
glm::mat4 modelMatrix;
s_entity(s_entity* myParent, Mesh &myMesh, Material &myMat)
{
parent = myParent;
mesh = myMesh;
mat = myMat;
}
} Entity;
// lights
std::vector<Entity*> entities;
Camera* camera;
public:
Scene();
~Scene();
void addEntity(Mesh& mesh, Material& mat);
void addEntity(Mesh& mesh);
void drawEntities(GLuint programId);
void setCamera(Camera* myCamera);
Camera* getCamera();
};
#endif // SCENE_H

95
shader.cpp Normal file
View File

@ -0,0 +1,95 @@
#include "shader.h"
#include <glew/glew.h>
#include <QFile>
#include <QTextStream>
#include <iostream>
#include "glassert.h"
Shader::Shader(const QString &vertFilename, const QString &fragFilename)
{
program = glAssert(glCreateProgram());
GLuint vertexShaderId = createShader(vertFilename, GL_VERTEX_SHADER);
GLuint fragmentShaderId = createShader(fragFilename, GL_FRAGMENT_SHADER);
glAssert(glAttachShader(program, vertexShaderId));
glAssert(glAttachShader(program, fragmentShaderId));
glAssert(glBindAttribLocation(program, 0, "inPosition"));
glAssert(glBindAttribLocation(program, 1, "inNormal"));
glAssert(glBindAttribLocation(program, 2, "inTexCoord"));
glAssert(glLinkProgram(program));
// check errors
GLint linked;
glAssert(glGetProgramiv(program, GL_LINK_STATUS, &linked));
if (!linked) {
std::cerr << "Program not linked" << std::endl;
printProgramInfoLog(program);
program = 0;
}
}
QString Shader::fileToString(QString filename)
{
QFile f(filename);
if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL;
QTextStream in(&f);
return in.readAll();
}
GLuint Shader::createShader(QString filename, GLenum shaderType)
{
QString source = fileToString(filename);
glAssert(GLuint shaderId = glCreateShader(shaderType));
const GLchar *data = (const GLchar *)source.constData();
glAssert(glShaderSource(shaderId, 1, &data, NULL));
glAssert(glCompileShader(shaderId));
// check errors
GLint compiled;
glAssert(glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled));
if (!compiled) {
std::cerr << "[" << filename.toStdString() << "] Vertex shader not compiled : " << std::endl;
printShaderInfoLog(shaderId);
return 0;
}
else
return shaderId;
}
void Shader::printShaderInfoLog(GLuint shaderId)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glAssert(glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLogLen));
if (infoLogLen > 0) {
infoLog = new GLchar[infoLogLen];
glAssert(glGetShaderInfoLog(shaderId, infoLogLen, &charsWritten, infoLog));
std::cerr << "InfoLog:" << std::endl << infoLog << std::endl;
delete [] infoLog;
}
}
void Shader::printProgramInfoLog(GLuint programId)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glAssert(glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLen));
if (infoLogLen > 0) {
infoLog = new GLchar[infoLogLen];
glAssert(glGetProgramInfoLog(programId, infoLogLen, &charsWritten, infoLog));
std::cerr << "InfoLog:" << std::endl << infoLog << std::endl;
delete [] infoLog;
}
}
GLuint Shader::getProgramId()
{
return program;
}

21
shader.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef SHADER_H
#define SHADER_H
#include <glew/glew.h>
class QString;
class Shader
{
GLuint program;
QString fileToString(QString filename);
GLuint createShader(QString filename, GLenum shaderType);
void printShaderInfoLog(GLuint shaderId);
void printProgramInfoLog(GLuint programId);
public:
Shader(const QString &vertFilename, const QString &fragFilename);
GLuint getProgramId();
};
#endif // SHADER_H

44
sparrowRenderer.pro Normal file
View File

@ -0,0 +1,44 @@
#-------------------------------------------------
#
# Project created by QtCreator 2015-06-16T15:37:51
#
#-------------------------------------------------
QT += core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = sparrowRenderer
TEMPLATE = app
CONFIG += c++11
INCLUDEPATH += ../cpp_dependencies/include
win32 {
LIBS += -L../../cpp_dependencies/lib/win32
}
LIBS += -lglew32
SOURCES += main.cpp\
mainwindow.cpp \
myglwidget.cpp \
shader.cpp \
mesh.cpp \
camera.cpp \
sparrowrenderer.cpp \
scene.cpp \
material.cpp
HEADERS += mainwindow.h \
myglwidget.h \
shader.h \
mesh.h \
camera.h \
sparrowrenderer.h \
glassert.h \
scene.h \
material.h
FORMS += mainwindow.ui
OTHER_FILES += *.frag *.vert *.glsl

35
sparrowrenderer.cpp Normal file
View File

@ -0,0 +1,35 @@
#include "sparrowrenderer.h"
#include "shader.h"
#include "camera.h"
#include "scene.h"
#include "glassert.h"
#include <glew/glew.h>
#include <QString>
SparrowRenderer::SparrowRenderer(int width, int height)
{
shader = new Shader(QString("../phong.vert"), QString("../phong.frag"));
scene = new Scene();
scene->setCamera(new Camera(width, height));
}
SparrowRenderer::~SparrowRenderer()
{
delete(scene->getCamera());
delete(shader);
delete(scene);
}
void SparrowRenderer::resize(int width, int height)
{
scene->getCamera()->resize(width, height);
}
void SparrowRenderer::render()
{
// bind shader
GLuint programId = shader->getProgramId();
glAssert(glUseProgram(programId));
// draw geometry
scene->drawEntities(programId);
}

22
sparrowrenderer.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef SPARROWRENDERER_H
#define SPARROWRENDERER_H
class Camera;
class Shader;
class Scene;
class SparrowRenderer
{
Shader* shader;
Scene* scene;
public:
SparrowRenderer(int width, int height);
~SparrowRenderer();
void resize(int width, int height);
// Sparrow renderer's rendering pipeline
void render();
};
#endif // SPARROWRENDERER_H