130 lines
3.8 KiB
C++
130 lines
3.8 KiB
C++
#include "pixelpipeline.h"
|
|
#include <framebuffer.h>
|
|
#include <texture.h>
|
|
#include <shader.h>
|
|
#include <cstring>
|
|
#include <glm/vec2.hpp>
|
|
#include <qtutils.h>
|
|
#include "mapscene.h"
|
|
#include <parametricmesh.h>
|
|
#include <glm/ext.hpp>
|
|
|
|
#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)-1);
|
|
}
|
|
};
|
|
|
|
// PIPELINE
|
|
|
|
PixelPipeline::PixelPipeline(MapScene *map) :
|
|
m_map(map),
|
|
m_mapWidth(map->getWidth()),
|
|
m_mapHeight(map->getHeight()),
|
|
m_camera(0, 0, 1)
|
|
{
|
|
m_width = 256;
|
|
m_height = 256;
|
|
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);
|
|
updateChanges();
|
|
}
|
|
|
|
PixelPipeline::~PixelPipeline()
|
|
{
|
|
delete m_mapFBO;
|
|
delete m_mapTex;
|
|
delete m_texMapShader;
|
|
delete m_renderShader;
|
|
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);
|
|
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_mapTex->bind(0);
|
|
m_renderShader->bindInteger(m_renderShader->getLocation("colorMap"), 0);
|
|
|
|
glClearDepth(1);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glEnable(GL_DEPTH_TEST);
|
|
m_renderShader->bindMat4(m_renderShader->getLocation("mvp"), m_mvp);
|
|
m_toreiller->draw(m_renderShader);
|
|
}
|
|
|
|
void PixelPipeline::resizeGL(int w, int h)
|
|
{
|
|
m_width = w;
|
|
m_height = h;
|
|
m_mvp = glm::translate(glm::perspectiveFov(70.f, float(w), float(h), 0.1f, 10.f), glm::vec3(0, 0, -3));
|
|
}
|
|
|
|
void PixelPipeline::cameraZoom(int nbScrolls)
|
|
{
|
|
while(nbScrolls != 0)
|
|
{
|
|
if(nbScrolls > 0)
|
|
{
|
|
m_camera.z *= SCROLL_SPEED;
|
|
--nbScrolls;
|
|
}
|
|
else
|
|
{
|
|
m_camera.z /= SCROLL_SPEED;
|
|
++nbScrolls;
|
|
}
|
|
}
|
|
}
|