PixelWars/src/pixelpipeline.cpp
2016-05-19 00:11:03 +02:00

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;
}
}
}