#include "pixelpipeline.h" #include #include #include #include #include #include #include "mapscene.h" #include #include #define SCROLL_SPEED 0.998f class ToreillerGenerator : public MeshGenerator { public: virtual glm::vec3 evalUV(float u, float v) { const float MAGIC_RATIO = 1; glm::vec2 relUV = glm::vec2(u-0.5f, v-0.5f); float clockAngle = atan2(relUV.y, relUV.x); float depthAngle = glm::length(relUV)*3.1416f*MAGIC_RATIO; float r = sin(depthAngle); return glm::vec3(r*cos(clockAngle), r*sin(clockAngle), cos(depthAngle)); } }; // PIPELINE PixelPipeline::PixelPipeline(MapScene *map) : m_map(map), m_mapWidth(map->getWidth()), m_mapHeight(map->getHeight()), m_camera(0, 0, 1), m_showToreiller(true) { m_width = 256; m_height = 256; m_surfaceRatio = 1; m_flatSphere = 0; m_map->setPipeline(this); m_targetFBO = FrameBuffer::screen; m_mapFBO = new FrameBuffer(); m_mapTex = new Texture(GL_RGBA, GL_RGBA, m_mapWidth, m_mapHeight, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE); m_mapTex->setFiltering(GL_NEAREST); m_mapTex->setWrap(GL_CLAMP_TO_EDGE); m_mapFBO->addTexture(m_mapTex, GL_COLOR_ATTACHMENT0); m_mapFBO->initColorAttachments(); // set up vao ToreillerGenerator gen; m_toreiller = gen.generateParametricMesh(NULL, 40, 40, 1.0f); m_toreiller->computeNormals(); m_toreiller->mergeVertices(); m_toreiller->initGL(); std::string vertSource = QtUtils::fileToString(":shaders/shaders/pixel.vert.glsl").toStdString(); std::string fragSource = QtUtils::fileToString(":shaders/shaders/pixel.frag.glsl").toStdString(); m_texMapShader = new Shader(vertSource, fragSource); vertSource = QtUtils::fileToString(":shaders/shaders/world.vert.glsl").toStdString(); fragSource = QtUtils::fileToString(":shaders/shaders/world.frag.glsl").toStdString(); m_renderShader = new Shader(vertSource, fragSource); vertSource = QtUtils::fileToString(":shaders/shaders/skybox.vert.glsl").toStdString(); fragSource = QtUtils::fileToString(":shaders/shaders/skybox.frag.glsl").toStdString(); m_skyboxShader = new Shader(vertSource, fragSource); m_skyTexFront = new Texture(QtUtils::loadImage(":images/img/sky_front.png")); m_skyTexBack = new Texture(QtUtils::loadImage(":images/img/sky_back.png")); updateChanges(); } PixelPipeline::~PixelPipeline() { // shaders delete m_texMapShader; delete m_renderShader; delete m_skyboxShader; // textures delete m_mapTex; delete m_skyTexBack; delete m_skyTexFront; // framebuffers delete m_mapFBO; // meshes delete m_toreiller; delete m_map; } void PixelPipeline::updateChanges() { if(m_map->updateNecessary()) { m_mapFBO->bindFBO(); glViewport(0, 0, m_mapWidth, m_mapHeight); m_texMapShader->bind(); m_texMapShader->bindVec2(m_texMapShader->getLocation("texRatio"), glm::vec2(2.0f/m_mapWidth, 2.0f/m_mapHeight)); m_map->draw(); } } void PixelPipeline::renderGL(Scene *scene) { m_targetFBO->bindFBO(); glViewport(0, 0, m_width, m_height); glClearColor(0, 0, 0, 1); glDisable(GL_BLEND); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glClearDepth(1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); m_skyboxShader->bind(); m_skyboxShader->bindVec3(m_skyboxShader->getLocation("camera"), m_camera); m_renderShader->bindVec2(m_skyboxShader->getLocation("worldSize"), glm::vec2(m_mapWidth, m_mapHeight)); m_skyboxShader->bindVec2(m_skyboxShader->getLocation("screenSize"), glm::vec2(m_width, m_height)); m_skyboxShader->bindFloat(m_skyboxShader->getLocation("surfaceRatio"), m_surfaceRatio); m_skyboxShader->bindFloat(m_skyboxShader->getLocation("flatSphere"), m_flatSphere); m_skyTexFront->bind(0); m_skyTexBack->bind(1); m_skyboxShader->bindInteger(m_skyboxShader->getLocation("frontMap"), 0); m_skyboxShader->bindInteger(m_skyboxShader->getLocation("backMap"), 1); m_skyboxShader->bindMat4(m_skyboxShader->getLocation("mvp"), m_proj); m_toreiller->draw(m_skyboxShader); glDepthMask(GL_TRUE); if(m_showToreiller) { m_renderShader->bind(); m_renderShader->bindVec3(m_renderShader->getLocation("camera"), m_camera); m_renderShader->bindVec2(m_renderShader->getLocation("worldSize"), glm::vec2(m_mapWidth, m_mapHeight)); m_renderShader->bindVec2(m_renderShader->getLocation("screenSize"), glm::vec2(m_width, m_height)); m_renderShader->bindFloat(m_renderShader->getLocation("surfaceRatio"), m_surfaceRatio); m_renderShader->bindFloat(m_renderShader->getLocation("flatSphere"), m_flatSphere); m_mapTex->bind(0); m_renderShader->bindInteger(m_renderShader->getLocation("colorMap"), 0); glm::mat4 mvp = m_proj * m_view; m_renderShader->bindMat4(m_renderShader->getLocation("mvp"), mvp); m_toreiller->draw(m_renderShader); } } void PixelPipeline::resizeGL(int w, int h) { m_width = w; m_height = h; m_proj = glm::perspectiveFov(70.f, float(w), float(h), 0.1f, 10.f); m_view = glm::translate(glm::mat4(), glm::vec3(0, 0, -3)); } void PixelPipeline::cameraMove(int x, int y) { m_camera.x -= 2*x/(m_camera.z*m_width); m_camera.y += 2*y/(m_camera.z*m_height); } void PixelPipeline::cameraZoom(int nbScrolls) { while(nbScrolls != 0) { if(nbScrolls > 0) { m_camera.z *= SCROLL_SPEED; --nbScrolls; } else { m_camera.z /= SCROLL_SPEED; ++nbScrolls; } } if(m_camera.z > m_mapHeight/4) m_camera.z = m_mapHeight/4; else if(m_camera.z < 1) m_camera.z = 1; } Coord PixelPipeline::getToreillerPos(int mouseX, int mouseY) { }