diff --git a/myglwidget.cpp b/myglwidget.cpp index b019f0d..a7c7257 100644 --- a/myglwidget.cpp +++ b/myglwidget.cpp @@ -8,6 +8,7 @@ #include "skybox.h" #include "utils.h" #include "texture.h" +#include "sparrowrenderer.h" #include #include #include @@ -15,62 +16,31 @@ MyGLWidget::MyGLWidget(QWidget *parent) : QGLWidget(parent), - scene(NULL) + renderer(NULL) {} MyGLWidget::~MyGLWidget() { - if(scene != NULL) - delete(scene); + if(renderer != NULL) + delete(renderer); } -void MyGLWidget::initializeGL() +Scene* MyGLWidget::buildScene() { - 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())); - - buildScene(); - controller.setScene(scene); -} - -void MyGLWidget::buildScene() -{ - scene = new Scene(); + Scene* scene = new Scene(); Camera* cam = new Camera(width(), height()); - cam->moveTo(glm::vec3(-1, 0, 0)); - cam->lookAt(glm::vec3(0, 0, 0)); + cam->moveTo(glm::vec3(0, 0, 3)); + cam->lookAt(glm::vec2(0, 0)); scene->setCamera(cam); Mesh* myGrid = new Sphere(2); myGrid->initGL(); - QString vertSource = Utils::fileToString("../phong.vert"); - QString fragSource = Utils::fileToString("../phong.frag"); - Shader* shader = new Shader(&vertSource, &fragSource); + 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); Texture* tex = new Texture("../data/noise.png"); mat->setTexture(tex); - QString filenames[6] = { + std::string filenames[6] = { "../data/skybox_ft", "../data/skybox_bk", "../data/skybox_up", "../data/skybox_dn", "../data/skybox_lf", "../data/skybox_rt" @@ -78,20 +48,27 @@ void MyGLWidget::buildScene() SkyBox* skybox = new SkyBox(filenames); scene->addEntity(skybox); 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) { - glAssert(glViewport(0, 0, width, height)); - scene->getCamera()->resize(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)); - scene->drawAll(); + renderer->render(); } void MyGLWidget::mouseMoveEvent(QMouseEvent *e) diff --git a/myglwidget.h b/myglwidget.h index 3d2f216..cfe2afc 100644 --- a/myglwidget.h +++ b/myglwidget.h @@ -5,6 +5,7 @@ #include class Scene; +class SparrowRenderer; namespace Ui { class MyGLWidget; @@ -14,7 +15,7 @@ class MyGLWidget : public QGLWidget { Q_OBJECT - Scene* scene; + SparrowRenderer* renderer; SceneController controller; QPoint last; @@ -24,7 +25,7 @@ public: protected: void initializeGL(); - void buildScene(); + Scene* buildScene(); void resizeGL(int width, int height); void paintGL(); diff --git a/scenecontroller.h b/scenecontroller.h index eac10c8..6916869 100644 --- a/scenecontroller.h +++ b/scenecontroller.h @@ -8,6 +8,7 @@ class Camera; class SceneController { +protected: Camera* camera; Scene* scene; int grabbed; @@ -15,9 +16,9 @@ public: SceneController() : camera(NULL), scene(NULL), grabbed(0) {} void setScene(Scene* myScene); - void mouseMove(int dx, int dy); - void mouseEvent(int button, bool state); - void keyEvent(int key, bool state); + virtual void mouseMove(int dx, int dy); + virtual void mouseEvent(int button, bool state); + virtual void keyEvent(int key, bool state); }; #endif // SCENECONTROLLER_H diff --git a/shader.cpp b/shader.cpp index 7f4661e..94324c2 100644 --- a/shader.cpp +++ b/shader.cpp @@ -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_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()); @@ -48,10 +48,10 @@ Shader::~Shader() 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)); - const GLchar *data = (const GLchar *)source->toStdString().c_str(); + const GLchar *data = (const GLchar *)source.c_str(); glAssert(glShaderSource(shaderId, 1, &data, NULL)); glAssert(glCompileShader(shaderId)); diff --git a/shader.h b/shader.h index 1923648..01046e0 100644 --- a/shader.h +++ b/shader.h @@ -4,19 +4,18 @@ #include #include #include -#include class Shader { static const std::string DEFAULT_VERT; static const std::string DEFAULT_FRAG; GLuint program; - GLuint createShader(const QString* filename, GLenum shaderType); + GLuint createShader(const std::string &source, GLenum shaderType); void printShaderInfoLog(GLuint shaderId); void printProgramInfoLog(GLuint programId); public: - Shader(const QString* vertexSource, const QString* fragmentSource); + Shader(const std::string &vertexSource, const std::string &fragmentSource); ~Shader(); GLuint getLocation(std::string attribName); diff --git a/skybox.cpp b/skybox.cpp index f3d9c26..5267dbf 100644 --- a/skybox.cpp +++ b/skybox.cpp @@ -6,9 +6,9 @@ #include "glm/glm.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); // set up vao @@ -84,7 +84,7 @@ const GLfloat SkyBox::skyboxVertices[] = { 1.0f, -1.0f, 1.0f }; -const QString SkyBox::vertSource = +const std::string SkyBox::vertSource = "#version 330 core\n\ layout(location = 0)in vec3 inPosition;\n\ out vec3 varTexCoord;\n\ @@ -95,7 +95,7 @@ const QString SkyBox::vertSource = varTexCoord = inPosition;\n\ }\n"; -const QString SkyBox::fragSource = +const std::string SkyBox::fragSource = "#version 330 core\n\ in vec3 varTexCoord;\n\ out vec4 outColor;\n\ diff --git a/skybox.h b/skybox.h index b3880ba..6d8739b 100644 --- a/skybox.h +++ b/skybox.h @@ -3,19 +3,18 @@ #include "entity.h" #include - -class QString; +#include class SkyBox : public Entity { private: static const GLfloat skyboxVertices[]; - static const QString vertSource; - static const QString fragSource; + static const std::string vertSource; + static const std::string fragSource; GLuint vao; GLuint vbo; public: - SkyBox(const QString filename[6]); + SkyBox(const std::string filename[6]); ~SkyBox(); virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix); }; diff --git a/skyboxmaterial.cpp b/skyboxmaterial.cpp index 46614d9..1ca4fa1 100644 --- a/skyboxmaterial.cpp +++ b/skyboxmaterial.cpp @@ -1,7 +1,7 @@ #include "skyboxmaterial.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); } diff --git a/skyboxmaterial.h b/skyboxmaterial.h index 6b6a82b..aae6b23 100644 --- a/skyboxmaterial.h +++ b/skyboxmaterial.h @@ -8,7 +8,7 @@ class Texture; class SkyBoxMaterial : public Material { public: - SkyBoxMaterial(Shader* myShader, const QString filenames[6]); + SkyBoxMaterial(Shader* myShader, const std::string filenames[6]); virtual void bindAttributes(); private: diff --git a/sparrowRenderer.pro b/sparrowRenderer.pro index 20ceb3c..a170e76 100644 --- a/sparrowRenderer.pro +++ b/sparrowRenderer.pro @@ -35,7 +35,8 @@ SOURCES += main.cpp\ skybox.cpp \ entity.cpp \ utils.cpp \ - lights.cpp + lights.cpp \ + sparrowrenderer.cpp HEADERS += mainwindow.h \ myglwidget.h \ @@ -54,7 +55,8 @@ HEADERS += mainwindow.h \ skybox.h \ entity.h \ utils.h \ - lights.h + lights.h \ + sparrowrenderer.h FORMS += mainwindow.ui diff --git a/sparrowrenderer.cpp b/sparrowrenderer.cpp new file mode 100644 index 0000000..c10963f --- /dev/null +++ b/sparrowrenderer.cpp @@ -0,0 +1,51 @@ +#include "sparrowrenderer.h" +#include +#include +#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(); +} diff --git a/sparrowrenderer.h b/sparrowrenderer.h new file mode 100644 index 0000000..346c75f --- /dev/null +++ b/sparrowrenderer.h @@ -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 diff --git a/sphere.cpp b/sphere.cpp index 2ba9b12..f17747c 100644 --- a/sphere.cpp +++ b/sphere.cpp @@ -23,12 +23,12 @@ Sphere::Sphere(int n) int bottom = 7; int offset = (i+1)%5; // top cap - addFace(0, top+offset, top+i); + addFace(0, top+i, top+offset); // bottom cap - addFace(6, bottom+i, bottom+offset); + addFace(6, bottom+offset, bottom+i); // middle ribbon - addFace(top+i, top+offset, bottom+i); - addFace(top+offset, bottom+offset, bottom+i); + addFace(top+i, bottom+i, top+offset); + addFace(top+offset, bottom+i, bottom+offset); } // geodesic subdivisions : @@ -73,11 +73,11 @@ int Sphere::getEdge(int a, int b) v.normal = v.position; // 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 newV = acos(v.position.y)/M_PI; - v.texCoord = glm::vec2(newU - floor(newU), newV); + //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; + //v.texCoord = glm::vec2(newU - floor(newU), newV); // alternative, u/v moyennés : - //v.texcoord_ = (v0.texcoord_ + v1.texcoord_)/2.f; + v.texCoord = (v0.texCoord + v1.texCoord)/2.f; vid = vertices.size(); addVertex(v); diff --git a/texture.cpp b/texture.cpp index c9bc6c5..c6b260d 100644 --- a/texture.cpp +++ b/texture.cpp @@ -1,18 +1,18 @@ #include "texture.h" #include "glassert.h" -#include +#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(glBindTexture(type, texId)); createTexture(filename, GL_TEXTURE_2D); 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(glGenTextures(1, &texId)); @@ -31,12 +31,12 @@ Texture::~Texture() 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 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) diff --git a/texture.h b/texture.h index 59ca09c..87f5d3e 100644 --- a/texture.h +++ b/texture.h @@ -2,9 +2,9 @@ #define TEXTURE_H #include +#include class QImage; -class QString; class Texture { @@ -12,14 +12,14 @@ private: GLuint texId; GLenum type; - void createTexture(QString filename, GLenum type); + void createTexture(std::string filename, GLenum type); void setWrap(GLint wrap); void setFiltering(GLint filter); public: // creates a standard texture from an image - Texture(const QString filename); + Texture(const std::string filename); // creates a cubeMap from 6 images - Texture(const QString filename[6]); + Texture(const std::string filename[6]); ~Texture(); void bind(int slot); diff --git a/utils.cpp b/utils.cpp index 45bbd7d..0f94d2f 100644 --- a/utils.cpp +++ b/utils.cpp @@ -1,12 +1,43 @@ #include "utils.h" #include #include +#include -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)) return NULL; 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(); } diff --git a/utils.h b/utils.h index 60f5758..bda6d3a 100644 --- a/utils.h +++ b/utils.h @@ -1,12 +1,26 @@ #ifndef UTILS_H #define UTILS_H -class QString; +#include +class QImage; class Utils { 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