161 lines
3.3 KiB
C++
161 lines
3.3 KiB
C++
#include "DrawContext.hpp"
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#include <utility>
|
|
|
|
#include "Batch2D.hpp"
|
|
#include "Framebuffer.hpp"
|
|
#include "window/Window.hpp"
|
|
|
|
static void set_blend_mode(BlendMode mode) {
|
|
switch (mode) {
|
|
case BlendMode::normal:
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
break;
|
|
case BlendMode::addition:
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
break;
|
|
case BlendMode::inversion:
|
|
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
DrawContext::DrawContext(
|
|
const DrawContext* parent,
|
|
Viewport viewport,
|
|
Batch2D* g2d
|
|
) : parent(parent),
|
|
viewport(std::move(viewport)),
|
|
g2d(g2d),
|
|
flushable(g2d)
|
|
{}
|
|
|
|
DrawContext::~DrawContext() {
|
|
if (flushable) {
|
|
flushable->flush();
|
|
}
|
|
|
|
while (scissorsCount--) {
|
|
Window::popScissor();
|
|
}
|
|
|
|
if (parent == nullptr)
|
|
return;
|
|
|
|
if (fbo != parent->fbo) {
|
|
if (fbo) {
|
|
fbo->unbind();
|
|
}
|
|
if (parent->fbo) {
|
|
parent->fbo->bind();
|
|
}
|
|
}
|
|
|
|
Window::viewport(
|
|
0, 0,
|
|
parent->viewport.getWidth(),
|
|
parent->viewport.getHeight()
|
|
);
|
|
|
|
if (depthMask != parent->depthMask) {
|
|
glDepthMask(parent->depthMask);
|
|
}
|
|
if (depthTest != parent->depthTest) {
|
|
if (depthTest) glDisable(GL_DEPTH_TEST);
|
|
else glEnable(GL_DEPTH_TEST);
|
|
}
|
|
if (cullFace != parent->cullFace) {
|
|
if (cullFace) glDisable(GL_CULL_FACE);
|
|
else glEnable(GL_CULL_FACE);
|
|
}
|
|
if (blendMode != parent->blendMode) {
|
|
set_blend_mode(parent->blendMode);
|
|
}
|
|
if (lineWidth != parent->lineWidth) {
|
|
glLineWidth(parent->lineWidth);
|
|
}
|
|
}
|
|
|
|
const Viewport& DrawContext::getViewport() const {
|
|
return viewport;
|
|
}
|
|
|
|
Batch2D* DrawContext::getBatch2D() const {
|
|
return g2d;
|
|
}
|
|
|
|
DrawContext DrawContext::sub(Flushable* flushable) const {
|
|
auto ctx = DrawContext(*this);
|
|
ctx.parent = this;
|
|
ctx.flushable = flushable;
|
|
ctx.scissorsCount = 0;
|
|
return ctx;
|
|
}
|
|
|
|
void DrawContext::setViewport(const Viewport& viewport) {
|
|
this->viewport = viewport;
|
|
Window::viewport(
|
|
0, 0,
|
|
viewport.getWidth(),
|
|
viewport.getHeight()
|
|
);
|
|
}
|
|
|
|
void DrawContext::setFramebuffer(Framebuffer* fbo) {
|
|
if (this->fbo == fbo)
|
|
return;
|
|
this->fbo = fbo;
|
|
if (fbo) {
|
|
fbo->bind();
|
|
}
|
|
}
|
|
|
|
void DrawContext::setDepthMask(bool flag) {
|
|
if (depthMask == flag)
|
|
return;
|
|
depthMask = flag;
|
|
glDepthMask(GL_FALSE + flag);
|
|
}
|
|
|
|
void DrawContext::setDepthTest(bool flag) {
|
|
if (depthTest == flag)
|
|
return;
|
|
depthTest = flag;
|
|
if (flag) {
|
|
glEnable(GL_DEPTH_TEST);
|
|
} else {
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
}
|
|
|
|
void DrawContext::setCullFace(bool flag) {
|
|
if (cullFace == flag)
|
|
return;
|
|
cullFace = flag;
|
|
if (flag) {
|
|
glEnable(GL_CULL_FACE);
|
|
} else {
|
|
glDisable(GL_CULL_FACE);
|
|
}
|
|
}
|
|
|
|
void DrawContext::setBlendMode(BlendMode mode) {
|
|
if (blendMode == mode)
|
|
return;
|
|
blendMode = mode;
|
|
set_blend_mode(mode);
|
|
}
|
|
|
|
void DrawContext::setScissors(const glm::vec4& area) {
|
|
Window::pushScissor(area);
|
|
scissorsCount++;
|
|
}
|
|
|
|
void DrawContext::setLineWidth(float width) {
|
|
lineWidth = width;
|
|
glLineWidth(width);
|
|
}
|