lots of refactoring, added SparrowRenderer class, moved all Qt dependencies to Utils class

This commit is contained in:
Anselme 2015-06-30 20:05:16 +02:00
parent 1bf29cac13
commit 26bfe5566b
17 changed files with 187 additions and 95 deletions

View File

@ -8,6 +8,7 @@
#include "skybox.h" #include "skybox.h"
#include "utils.h" #include "utils.h"
#include "texture.h" #include "texture.h"
#include "sparrowrenderer.h"
#include <iostream> #include <iostream>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <QKeyEvent> #include <QKeyEvent>
@ -15,62 +16,31 @@
MyGLWidget::MyGLWidget(QWidget *parent) : MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent), QGLWidget(parent),
scene(NULL) renderer(NULL)
{} {}
MyGLWidget::~MyGLWidget() MyGLWidget::~MyGLWidget()
{ {
if(scene != NULL) if(renderer != NULL)
delete(scene); delete(renderer);
} }
void MyGLWidget::initializeGL() Scene* MyGLWidget::buildScene()
{ {
makeCurrent(); Scene* scene = new Scene();
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()));
buildScene();
controller.setScene(scene);
}
void MyGLWidget::buildScene()
{
scene = new Scene();
Camera* cam = new Camera(width(), height()); Camera* cam = new Camera(width(), height());
cam->moveTo(glm::vec3(-1, 0, 0)); cam->moveTo(glm::vec3(0, 0, 3));
cam->lookAt(glm::vec3(0, 0, 0)); cam->lookAt(glm::vec2(0, 0));
scene->setCamera(cam); scene->setCamera(cam);
Mesh* myGrid = new Sphere(2); Mesh* myGrid = new Sphere(2);
myGrid->initGL(); myGrid->initGL();
QString vertSource = Utils::fileToString("../phong.vert"); std::string vertSource = Utils::fileToString("../phong.vert");
QString 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);
Texture* tex = new Texture("../data/noise.png"); Texture* tex = new Texture("../data/noise.png");
mat->setTexture(tex); mat->setTexture(tex);
QString filenames[6] = { std::string filenames[6] = {
"../data/skybox_ft", "../data/skybox_bk", "../data/skybox_ft", "../data/skybox_bk",
"../data/skybox_up", "../data/skybox_dn", "../data/skybox_up", "../data/skybox_dn",
"../data/skybox_lf", "../data/skybox_rt" "../data/skybox_lf", "../data/skybox_rt"
@ -78,20 +48,27 @@ void MyGLWidget::buildScene()
SkyBox* skybox = new SkyBox(filenames); SkyBox* skybox = new SkyBox(filenames);
scene->addEntity(skybox); scene->addEntity(skybox);
scene->addEntity(myGrid, mat); scene->addEntity(myGrid, mat);
return scene;
}
void MyGLWidget::initializeGL()
{
makeCurrent();
renderer = new SparrowRenderer(width(), height());
Scene* scene = buildScene();
renderer->setScene(scene);
controller.setScene(scene);
} }
void MyGLWidget::resizeGL(int width, int height) void MyGLWidget::resizeGL(int width, int height)
{ {
glAssert(glViewport(0, 0, width, height)); renderer->resize(width, height);
scene->getCamera()->resize(width, height);
updateGL(); updateGL();
} }
void MyGLWidget::paintGL() void MyGLWidget::paintGL()
{ {
glAssert(glClearColor(0.60, 0.65, 0.75, 1.0)); renderer->render();
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
scene->drawAll();
} }
void MyGLWidget::mouseMoveEvent(QMouseEvent *e) void MyGLWidget::mouseMoveEvent(QMouseEvent *e)

View File

@ -5,6 +5,7 @@
#include <QGLWidget> #include <QGLWidget>
class Scene; class Scene;
class SparrowRenderer;
namespace Ui { namespace Ui {
class MyGLWidget; class MyGLWidget;
@ -14,7 +15,7 @@ class MyGLWidget : public QGLWidget
{ {
Q_OBJECT Q_OBJECT
Scene* scene; SparrowRenderer* renderer;
SceneController controller; SceneController controller;
QPoint last; QPoint last;
@ -24,7 +25,7 @@ public:
protected: protected:
void initializeGL(); void initializeGL();
void buildScene(); Scene* buildScene();
void resizeGL(int width, int height); void resizeGL(int width, int height);
void paintGL(); void paintGL();

View File

@ -8,6 +8,7 @@ class Camera;
class SceneController class SceneController
{ {
protected:
Camera* camera; Camera* camera;
Scene* scene; Scene* scene;
int grabbed; int grabbed;
@ -15,9 +16,9 @@ public:
SceneController() : camera(NULL), scene(NULL), grabbed(0) {} SceneController() : camera(NULL), scene(NULL), grabbed(0) {}
void setScene(Scene* myScene); void setScene(Scene* myScene);
void mouseMove(int dx, int dy); virtual void mouseMove(int dx, int dy);
void mouseEvent(int button, bool state); virtual void mouseEvent(int button, bool state);
void keyEvent(int key, bool state); virtual void keyEvent(int key, bool state);
}; };
#endif // SCENECONTROLLER_H #endif // SCENECONTROLLER_H

View File

@ -7,7 +7,7 @@
const std::string Shader::DEFAULT_VERT = "#version 330\nlayout(location = 0)in vec3 inPosition;\nvoid main(){gl_Position = vec4(inPosition, 1.0);}"; const std::string Shader::DEFAULT_VERT = "#version 330\nlayout(location = 0)in vec3 inPosition;\nvoid main(){gl_Position = vec4(inPosition, 1.0);}";
const std::string Shader::DEFAULT_FRAG = "#version 330\nlayout(location = 0)out vec4 outColor;\nvoid main(){outColor = vec4(1, 0, 0, 1);}"; const std::string Shader::DEFAULT_FRAG = "#version 330\nlayout(location = 0)out vec4 outColor;\nvoid main(){outColor = vec4(1, 0, 0, 1);}";
Shader::Shader(const QString* vertexSource, const QString* fragmentSource) Shader::Shader(const std::string &vertexSource, const std::string &fragmentSource)
{ {
program = glAssert(glCreateProgram()); program = glAssert(glCreateProgram());
@ -48,10 +48,10 @@ Shader::~Shader()
glAssert(glDeleteProgram(program)); glAssert(glDeleteProgram(program));
} }
GLuint Shader::createShader(const QString* source, GLenum shaderType) GLuint Shader::createShader(const std::string &source, GLenum shaderType)
{ {
glAssert(GLuint shaderId = glCreateShader(shaderType)); glAssert(GLuint shaderId = glCreateShader(shaderType));
const GLchar *data = (const GLchar *)source->toStdString().c_str(); const GLchar *data = (const GLchar *)source.c_str();
glAssert(glShaderSource(shaderId, 1, &data, NULL)); glAssert(glShaderSource(shaderId, 1, &data, NULL));
glAssert(glCompileShader(shaderId)); glAssert(glCompileShader(shaderId));

View File

@ -4,19 +4,18 @@
#include <glew/glew.h> #include <glew/glew.h>
#include <string> #include <string>
#include <glm/fwd.hpp> #include <glm/fwd.hpp>
#include <QString>
class Shader class Shader
{ {
static const std::string DEFAULT_VERT; static const std::string DEFAULT_VERT;
static const std::string DEFAULT_FRAG; static const std::string DEFAULT_FRAG;
GLuint program; GLuint program;
GLuint createShader(const QString* filename, GLenum shaderType); GLuint createShader(const std::string &source, GLenum shaderType);
void printShaderInfoLog(GLuint shaderId); void printShaderInfoLog(GLuint shaderId);
void printProgramInfoLog(GLuint programId); void printProgramInfoLog(GLuint programId);
public: public:
Shader(const QString* vertexSource, const QString* fragmentSource); Shader(const std::string &vertexSource, const std::string &fragmentSource);
~Shader(); ~Shader();
GLuint getLocation(std::string attribName); GLuint getLocation(std::string attribName);

View File

@ -6,9 +6,9 @@
#include "glm/glm.hpp" #include "glm/glm.hpp"
#include "glm/ext.hpp" #include "glm/ext.hpp"
SkyBox::SkyBox(const QString filename[6]) : Entity(NULL, NULL, NULL) SkyBox::SkyBox(const std::string filename[6]) : Entity(NULL, NULL, NULL)
{ {
Shader* shader = new Shader(&vertSource, &fragSource); Shader* shader = new Shader(vertSource, fragSource);
mat = new SkyBoxMaterial(shader, filename); mat = new SkyBoxMaterial(shader, filename);
// set up vao // set up vao
@ -84,7 +84,7 @@ const GLfloat SkyBox::skyboxVertices[] = {
1.0f, -1.0f, 1.0f 1.0f, -1.0f, 1.0f
}; };
const QString SkyBox::vertSource = const std::string SkyBox::vertSource =
"#version 330 core\n\ "#version 330 core\n\
layout(location = 0)in vec3 inPosition;\n\ layout(location = 0)in vec3 inPosition;\n\
out vec3 varTexCoord;\n\ out vec3 varTexCoord;\n\
@ -95,7 +95,7 @@ const QString SkyBox::vertSource =
varTexCoord = inPosition;\n\ varTexCoord = inPosition;\n\
}\n"; }\n";
const QString SkyBox::fragSource = const std::string SkyBox::fragSource =
"#version 330 core\n\ "#version 330 core\n\
in vec3 varTexCoord;\n\ in vec3 varTexCoord;\n\
out vec4 outColor;\n\ out vec4 outColor;\n\

View File

@ -3,19 +3,18 @@
#include "entity.h" #include "entity.h"
#include <glew/glew.h> #include <glew/glew.h>
#include <string>
class QString;
class SkyBox : public Entity class SkyBox : public Entity
{ {
private: private:
static const GLfloat skyboxVertices[]; static const GLfloat skyboxVertices[];
static const QString vertSource; static const std::string vertSource;
static const QString fragSource; static const std::string fragSource;
GLuint vao; GLuint vao;
GLuint vbo; GLuint vbo;
public: public:
SkyBox(const QString filename[6]); SkyBox(const std::string filename[6]);
~SkyBox(); ~SkyBox();
virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix); virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix);
}; };

View File

@ -1,7 +1,7 @@
#include "skyboxmaterial.h" #include "skyboxmaterial.h"
#include "texture.h" #include "texture.h"
SkyBoxMaterial::SkyBoxMaterial(Shader* myShader, const QString filenames[6]) : Material(myShader) SkyBoxMaterial::SkyBoxMaterial(Shader* myShader, const std::string filenames[6]) : Material(myShader)
{ {
skyboxTex = new Texture(filenames); skyboxTex = new Texture(filenames);
} }

View File

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

View File

@ -35,7 +35,8 @@ SOURCES += main.cpp\
skybox.cpp \ skybox.cpp \
entity.cpp \ entity.cpp \
utils.cpp \ utils.cpp \
lights.cpp lights.cpp \
sparrowrenderer.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
myglwidget.h \ myglwidget.h \
@ -54,7 +55,8 @@ HEADERS += mainwindow.h \
skybox.h \ skybox.h \
entity.h \ entity.h \
utils.h \ utils.h \
lights.h lights.h \
sparrowrenderer.h
FORMS += mainwindow.ui FORMS += mainwindow.ui

51
sparrowrenderer.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "sparrowrenderer.h"
#include <glew/glew.h>
#include <iostream>
#include "glassert.h"
#include "camera.h"
SparrowRenderer::SparrowRenderer(int width, int height)
{
glewExperimental = GL_TRUE;
GLenum err = glewInit();
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;
glAssert(glEnable(GL_DEPTH_TEST));
glAssert(glEnable(GL_CULL_FACE));
glAssert(glEnable(GL_TEXTURE_2D));
glAssert(glViewport(0, 0, width, height));
}
void SparrowRenderer::setScene(Scene* myScene)
{
scene = myScene;
}
void SparrowRenderer::resize(int width, int height)
{
glAssert(glViewport(0, 0, width, height));
if(scene != NULL)
scene->getCamera()->resize(width, height);
}
void SparrowRenderer::render()
{
glAssert(glClearColor(0.60, 0.65, 0.75, 1.0));
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
if(scene != NULL)
scene->drawAll();
}

17
sparrowrenderer.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SPARROWRENDERER_H
#define SPARROWRENDERER_H
#include "scene.h"
class SparrowRenderer
{
Scene* scene;
// TODO : data bank
public:
SparrowRenderer(int width, int height);
void setScene(Scene* myScene);
void resize(int width, int height);
void render();
};
#endif // SPARROWRENDERER_H

View File

@ -23,12 +23,12 @@ Sphere::Sphere(int n)
int bottom = 7; int bottom = 7;
int offset = (i+1)%5; int offset = (i+1)%5;
// top cap // top cap
addFace(0, top+offset, top+i); addFace(0, top+i, top+offset);
// bottom cap // bottom cap
addFace(6, bottom+i, bottom+offset); addFace(6, bottom+offset, bottom+i);
// middle ribbon // middle ribbon
addFace(top+i, top+offset, bottom+i); addFace(top+i, bottom+i, top+offset);
addFace(top+offset, bottom+offset, bottom+i); addFace(top+offset, bottom+i, bottom+offset);
} }
// geodesic subdivisions : // geodesic subdivisions :
@ -73,11 +73,11 @@ int Sphere::getEdge(int a, int b)
v.normal = v.position; v.normal = v.position;
// u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0 // u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0
float newU = (v.position.x < 0 ? 1.5f : 1.f) + atan(v.position.z/v.position.x)/(2*M_PI); //float newU = (v.position.x < 0 ? 1.5f : 1.f) + atan(v.position.z/v.position.x)/(2*M_PI);
float newV = acos(v.position.y)/M_PI; //float newV = acos(v.position.y)/M_PI;
v.texCoord = glm::vec2(newU - floor(newU), newV); //v.texCoord = glm::vec2(newU - floor(newU), newV);
// alternative, u/v moyennés : // alternative, u/v moyennés :
//v.texcoord_ = (v0.texcoord_ + v1.texcoord_)/2.f; v.texCoord = (v0.texCoord + v1.texCoord)/2.f;
vid = vertices.size(); vid = vertices.size();
addVertex(v); addVertex(v);

View File

@ -1,18 +1,18 @@
#include "texture.h" #include "texture.h"
#include "glassert.h" #include "glassert.h"
#include <QImage> #include "utils.h"
Texture::Texture(const QString filename) : type(GL_TEXTURE_2D) Texture::Texture(const std::string filename) : type(GL_TEXTURE_2D)
{ {
glAssert(glGenTextures(1, &texId)); glAssert(glGenTextures(1, &texId));
glAssert(glBindTexture(type, texId)); glAssert(glBindTexture(type, texId));
createTexture(filename, GL_TEXTURE_2D); createTexture(filename, GL_TEXTURE_2D);
setWrap(GL_REPEAT); setWrap(GL_REPEAT);
setFiltering(GL_NEAREST); setFiltering(GL_LINEAR);
} }
Texture::Texture(const QString filename[6]) : type(GL_TEXTURE_CUBE_MAP) Texture::Texture(const std::string filename[6]) : type(GL_TEXTURE_CUBE_MAP)
{ {
glAssert(glActiveTexture(GL_TEXTURE0)); glAssert(glActiveTexture(GL_TEXTURE0));
glAssert(glGenTextures(1, &texId)); glAssert(glGenTextures(1, &texId));
@ -31,12 +31,12 @@ Texture::~Texture()
glAssert(glDeleteTextures(1, &texId)); glAssert(glDeleteTextures(1, &texId));
} }
void Texture::createTexture(QString filename, GLenum textureSlot) void Texture::createTexture(std::string filename, GLenum textureSlot)
{ {
QImage img(filename); Utils::Image img(filename);
int bpp = (img.depth() == 32) ? GL_RGBA : GL_RGB; int bpp = (img.depth() == 32) ? GL_RGBA : GL_RGB;
int format = (img.depth() == 32) ? GL_BGRA : GL_BGR; int format = (img.depth() == 32) ? GL_BGRA : GL_BGR;
glAssert(glTexImage2D(textureSlot, 0, bpp, img.width(), img.height(), 0, format, GL_UNSIGNED_BYTE, img.bits())); glAssert(glTexImage2D(textureSlot, 0, bpp, img.width(), img.height(), 0, format, GL_UNSIGNED_BYTE, img.pixels()));
} }
void Texture::setWrap(GLint wrap) void Texture::setWrap(GLint wrap)

View File

@ -2,9 +2,9 @@
#define TEXTURE_H #define TEXTURE_H
#include <glew/glew.h> #include <glew/glew.h>
#include <string>
class QImage; class QImage;
class QString;
class Texture class Texture
{ {
@ -12,14 +12,14 @@ private:
GLuint texId; GLuint texId;
GLenum type; GLenum type;
void createTexture(QString filename, GLenum type); void createTexture(std::string filename, GLenum type);
void setWrap(GLint wrap); void setWrap(GLint wrap);
void setFiltering(GLint filter); void setFiltering(GLint filter);
public: public:
// creates a standard texture from an image // creates a standard texture from an image
Texture(const QString filename); Texture(const std::string filename);
// creates a cubeMap from 6 images // creates a cubeMap from 6 images
Texture(const QString filename[6]); Texture(const std::string filename[6]);
~Texture(); ~Texture();
void bind(int slot); void bind(int slot);

View File

@ -1,12 +1,43 @@
#include "utils.h" #include "utils.h"
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <QImage>
QString Utils::fileToString(const QString &filename) std::string Utils::fileToString(const std::string &filename)
{ {
QFile f(filename); QFile f(QString(filename.c_str()));
if(!f.open(QFile::ReadOnly | QFile::Text)) if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL; return NULL;
QTextStream in(&f); QTextStream in(&f);
return in.readAll(); return in.readAll().toStdString();
}
Utils::Image::Image(std::string filename)
{
img = new QImage(QString(filename.c_str()));
}
Utils::Image::~Image()
{
delete(img);
}
int Utils::Image::depth()
{
return img->depth();
}
int Utils::Image::width()
{
return img->width();
}
int Utils::Image::height()
{
return img->height();
}
void* Utils::Image::pixels()
{
return (void*)img->bits();
} }

18
utils.h
View File

@ -1,12 +1,26 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
class QString; #include <string>
class QImage;
class Utils class Utils
{ {
public: public:
static QString fileToString(const QString &filename); static std::string fileToString(const std::string &filename);
class Image
{
private:
QImage* img;
public:
Image(std::string filename);
~Image();
int depth();
int width();
int height();
void* pixels();
};
}; };
#endif // UTILS_H #endif // UTILS_H