Files
magnum-boostrap-qtquick/src/magnum_render.cpp

201 lines
5.3 KiB
C++
Raw Normal View History

2020-06-18 18:25:03 -06:00
#include <Corrade/Utility/DebugStl.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Math/Color.h>
#include <Magnum/MeshTools/Compile.h>
#include <Magnum/Platform/GLContext.h>
#include <Magnum/Primitives/Cube.h>
#include <Magnum/Primitives/Grid.h>
#include <Magnum/Trade/MeshData.h>
#include "magnum_render.h"
using namespace Magnum;
using namespace Math::Literals;
static const auto HUE_BG = 210.0_degf;
static const auto COLOR_BG = Color4::fromHsv({HUE_BG, .3f, .9f}, 1.f);
static const auto COLOR_GRID = Color4::fromHsv({HUE_BG, .3f, .7f}, 1.f);
2020-07-08 14:13:52 -06:00
MagnumRenderer::MagnumRenderer() : m_init(false) {}
2020-06-18 18:25:03 -06:00
2020-06-23 00:38:55 -06:00
MagnumRenderer::~MagnumRenderer() {
delete m_subjectObject;
delete m_subjectDrawable;
delete m_gridObject;
}
2020-06-18 18:25:03 -06:00
void MagnumRenderer::t(const float t) {
2020-06-23 00:38:55 -06:00
if (m_subjectDrawable)
m_subjectDrawable->t(t);
2020-06-18 18:25:03 -06:00
}
void MagnumRenderer::hue(float hue) {
2020-06-23 00:38:55 -06:00
if (m_subjectDrawable)
m_subjectDrawable->hue(hue);
2020-06-18 18:25:03 -06:00
}
void MagnumRenderer::count(int count) {
2020-06-22 23:43:06 -06:00
if (m_subjectDrawable)
m_subjectDrawable->count(count);
2020-06-18 18:25:03 -06:00
}
2020-06-23 16:29:36 -06:00
Containers::Optional<ArcBallCamera>& MagnumRenderer::camera() {
2020-06-23 00:38:55 -06:00
return m_camera;
}
2020-06-23 16:29:36 -06:00
float MagnumRenderer::lagging() {
if (m_camera)
return m_camera->lagging();
else
return 0.f;
}
void MagnumRenderer::lagging(float lagging) {
if (m_camera)
m_camera->setLagging(lagging);
}
/**
* @brief MagnumRenderer::lazyInitialize
*
*/
2020-06-18 18:25:03 -06:00
void MagnumRenderer::lazyInitialize() {
if (m_init) return;
// The Cube
{
m_subject = MeshTools::compile(Primitives::cubeSolid());
m_subjectObject = new Object3D{&m_scene};
(*m_subjectObject).translate(Vector3{0.f, 1.f, 0.f});
m_subjectShader = Shaders::Phong{};
m_subjectShader
.setShininess(20.f)
.setLightColor(Color3{1.f})
.setLightPosition(Vector3{-100.f, 100.f, 50.f});
2020-07-08 14:13:52 -06:00
m_subjectDrawable = new SubjectDrawable{*m_subjectObject, m_subjectShader, m_subject, m_drawables, 1, 0, 0};
2020-06-18 18:25:03 -06:00
}
// The Grid
{
m_grid = MeshTools::compile(Primitives::grid3DWireframe({15, 15}));
2020-06-22 23:43:06 -06:00
m_gridObject = new Object3D{&m_scene};
(*m_gridObject).rotateX(90.0_degf).scale(Vector3{8.0f});
2020-06-18 18:25:03 -06:00
m_gridShader = Shaders::Flat3D{};
m_gridShader.setColor(COLOR_GRID);
2020-06-23 00:38:55 -06:00
m_gridDrawable = new GridDrawable{*m_gridObject, m_gridShader, m_grid, m_drawables};
2020-06-18 18:25:03 -06:00
}
// The Camera
{
const Vector3 eye{-10.0f, 8.f, -6.f};
const Vector3 center{0.f, 1.f, 0.f};
const Vector3 up = Vector3::yAxis();
m_camera.emplace(m_scene, eye, center, up, 45.0_degf,
Vector2i{100, 100}, Vector2i{100, 100});
}
m_init = true;
}
void MagnumRenderer::reset(Platform::GLContext *ctx,
GL::Framebuffer fbo,
Vector2i windowSize,
Vector2i viewportSize) {
lazyInitialize();
m_camera->reshape(windowSize, viewportSize);
m_FBO = std::move(fbo);
m_ctx = ctx;
}
2020-06-23 16:29:36 -06:00
/**
* @brief MagnumRenderer::prepGLState
*
*/
2020-06-18 18:25:03 -06:00
void MagnumRenderer::prepGLState() {
GL::Renderer::setClearColor(COLOR_BG);
GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
GL::Renderer::enable(GL::Renderer::Feature::FaceCulling);
GL::Renderer::enable(GL::Renderer::Feature::Multisampling);
GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::LessOrEqual);
GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add,
GL::Renderer::BlendEquation::Add);
GL::Renderer::setBlendFunction(
GL::Renderer::BlendFunction::One,
GL::Renderer::BlendFunction::OneMinusSourceAlpha);
GL::Renderer::enable(GL::Renderer::Feature::Blending);
}
void MagnumRenderer::render() {
m_ctx->resetState(GL::Context::State::ExitExternal);
prepGLState();
m_FBO.bind();
m_FBO.clear(GL::FramebufferClear::Color |
GL::FramebufferClear::Depth);
m_camera->update();
m_camera->draw(m_drawables);
/** Use instead this to limit rendering to camera changes
* bool cameraChanged = m_camera->update();
* m_camera->draw(m_drawables);
* if (cameraChanged) {
2020-06-23 16:29:36 -06:00
* redraw(); // should call back to MagnumItem::update()
2020-06-18 18:25:03 -06:00
* } */
// ---
m_ctx->resetState(GL::Context::State::EnterExternal);
}
void GridDrawable::draw(const Matrix4 &transformation,
SceneGraph::Camera3D &camera) {
m_shader
.setTransformationProjectionMatrix(
camera.projectionMatrix()*transformation)
.draw(m_mesh);
}
void SubjectDrawable::draw(const Matrix4 &transformation,
SceneGraph::Camera3D &camera) {
2020-06-23 16:29:36 -06:00
// We only need to do this once in this draw call
2020-06-18 18:25:03 -06:00
m_shader
.setNormalMatrix(transformation.normalMatrix())
2020-06-22 23:43:06 -06:00
.setProjectionMatrix(camera.projectionMatrix());
2020-06-23 16:29:36 -06:00
2020-06-22 23:43:06 -06:00
static const float width = 3.f;
float x = -float(m_count)/2.f * width + width/2.f;
2020-06-23 16:29:36 -06:00
2020-06-22 23:43:06 -06:00
for (int i = 0; i < m_count; i++) {
2020-06-23 16:29:36 -06:00
// Change hue depending on position
2020-06-23 00:38:55 -06:00
const auto color = Color3::fromHsv({Rad(m_hue+float(i)*.2f), 1.f, 1.f});
m_shader
.setDiffuseColor(color)
.setAmbientColor(Color3::fromHsv({color.hue(), 1.0f, 0.3f}));
2020-06-23 16:29:36 -06:00
// Move in +x
2020-06-22 23:43:06 -06:00
m_shader
.setTransformationMatrix(
transformation *
2020-06-23 00:38:55 -06:00
Matrix4::translation({x, Math::sin(Rad(m_t*2.f+float(i))), 0.f}))
2020-06-22 23:43:06 -06:00
.draw(m_mesh);
x += width;
}
}
void SubjectDrawable::count(int count) {
m_count = count;
2020-06-18 18:25:03 -06:00
}
2020-06-23 00:38:55 -06:00
void SubjectDrawable::hue(float hue) {
m_hue = hue;
}
void SubjectDrawable::t(float t) {
m_t = t;
}