147 lines
4.5 KiB
C++
147 lines
4.5 KiB
C++
#include "canvas.h"
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
using namespace glm;
|
|
using namespace game::resource;
|
|
|
|
namespace game
|
|
{
|
|
GLuint Canvas::textureVAO = 0;
|
|
GLuint Canvas::textureVBO = 0;
|
|
GLuint Canvas::textureEBO = 0;
|
|
bool Canvas::isStaticInit = false;
|
|
|
|
Canvas::Canvas(vec2 size, bool isDefault)
|
|
{
|
|
this->size = size;
|
|
|
|
if (isDefault)
|
|
{
|
|
fbo = 0;
|
|
rbo = 0;
|
|
texture = 0;
|
|
this->isDefault = true;
|
|
}
|
|
else
|
|
{
|
|
glGenFramebuffers(1, &fbo);
|
|
glGenRenderbuffers(1, &rbo);
|
|
glGenTextures(1, &texture);
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture);
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x, size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
|
|
|
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, size.x, size.y);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
if (!isStaticInit)
|
|
{
|
|
glGenVertexArrays(1, &textureVAO);
|
|
glGenBuffers(1, &textureVBO);
|
|
glGenBuffers(1, &textureEBO);
|
|
|
|
glBindVertexArray(textureVAO);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, textureVBO);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 4, nullptr, GL_DYNAMIC_DRAW);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, textureEBO);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(TEXTURE_INDICES), TEXTURE_INDICES, GL_DYNAMIC_DRAW);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
|
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
|
|
|
|
glBindVertexArray(0);
|
|
}
|
|
}
|
|
|
|
Canvas::~Canvas()
|
|
{
|
|
if (!isDefault)
|
|
{
|
|
if (fbo) glDeleteFramebuffers(1, &fbo);
|
|
if (rbo) glDeleteRenderbuffers(1, &rbo);
|
|
if (texture) glDeleteTextures(1, &texture);
|
|
}
|
|
}
|
|
|
|
mat4 Canvas::view_get() const { return mat4{1.0f}; }
|
|
mat4 Canvas::projection_get() const
|
|
{
|
|
if (isDefault) return glm::ortho(0.0f, (float)size.x, (float)size.y, 0.0f, -1.0f, 1.0f);
|
|
return glm::ortho(0.0f, (float)size.x, 0.0f, (float)size.y, -1.0f, 1.0f);
|
|
}
|
|
|
|
void Canvas::texture_render(Shader& shader, GLuint textureId, mat4& model, vec4 tint, vec3 colorOffset,
|
|
float* vertices) const
|
|
{
|
|
auto view = view_get();
|
|
auto projection = projection_get();
|
|
|
|
glUseProgram(shader.id);
|
|
|
|
glUniform1i(glGetUniformLocation(shader.id, shader::UNIFORM_TEXTURE), 0);
|
|
glUniform3fv(glGetUniformLocation(shader.id, shader::UNIFORM_COLOR_OFFSET), 1, value_ptr(colorOffset));
|
|
glUniform4fv(glGetUniformLocation(shader.id, shader::UNIFORM_TINT), 1, value_ptr(tint));
|
|
|
|
glUniformMatrix4fv(glGetUniformLocation(shader.id, shader::UNIFORM_MODEL), 1, GL_FALSE, value_ptr(model));
|
|
glUniformMatrix4fv(glGetUniformLocation(shader.id, shader::UNIFORM_VIEW), 1, GL_FALSE, value_ptr(view));
|
|
glUniformMatrix4fv(glGetUniformLocation(shader.id, shader::UNIFORM_PROJECTION), 1, GL_FALSE, value_ptr(projection));
|
|
|
|
glBindVertexArray(textureVAO);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, textureVBO);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(TEXTURE_VERTICES), vertices, GL_DYNAMIC_DRAW);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, textureId);
|
|
|
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
|
|
glBindVertexArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
glUseProgram(0);
|
|
}
|
|
|
|
void Canvas::render(Shader& shader, mat4& model, vec4 tint, vec3 colorOffset) const
|
|
{
|
|
texture_render(shader, texture, model, tint, colorOffset);
|
|
}
|
|
|
|
void Canvas::bind() const
|
|
{
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
|
glViewport(0, 0, size.x, size.y);
|
|
}
|
|
|
|
void Canvas::clear(vec4 color) const
|
|
{
|
|
glClearColor(color.r, color.g, color.b, color.a);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
void Canvas::unbind() const
|
|
{
|
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
}
|
|
|
|
bool Canvas::is_valid() const { return fbo != 0 || isDefault; };
|
|
}
|