mirror of
https://github.com/MadeOfJelly/MushMachine.git
synced 2025-06-19 11:16:37 +02:00
initial import, >900commits predate this
This commit is contained in:
32
framework/opengl_primitives/src/mm/opengl/buffer.cpp
Normal file
32
framework/opengl_primitives/src/mm/opengl/buffer.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by FlaXxy on 21.05.2018.
|
||||
//
|
||||
|
||||
#include "./buffer.hpp"
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
Buffer::Buffer(const void* data, std::size_t size, GLenum usage) : _size(size) {
|
||||
glGenBuffers(1, &_handle);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _handle);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, usage);
|
||||
}
|
||||
|
||||
Buffer::~Buffer(void) {
|
||||
glDeleteBuffers(1,&_handle);
|
||||
}
|
||||
|
||||
void Buffer::bind(GLenum target) const {
|
||||
glBindBuffer(target, _handle);
|
||||
}
|
||||
|
||||
void Buffer::unbind(GLenum target) const {
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
|
||||
std::size_t Buffer::getSize(void) const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
35
framework/opengl_primitives/src/mm/opengl/buffer.hpp
Normal file
35
framework/opengl_primitives/src/mm/opengl/buffer.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by FlaXxy on 21.05.2018.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
namespace MM::OpenGL {
|
||||
/**
|
||||
* A fixed size buffer
|
||||
*/
|
||||
class Buffer {
|
||||
private:
|
||||
GLuint _handle = 0;
|
||||
std::size_t _size = 0;
|
||||
|
||||
public:
|
||||
Buffer(const void* data, std::size_t size, GLenum usage);
|
||||
~Buffer(void);
|
||||
|
||||
void bind(GLenum target) const;
|
||||
void unbind(GLenum target) const;
|
||||
|
||||
std::size_t getSize(void) const;
|
||||
};
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "../texture.hpp"
|
||||
|
||||
namespace MM::Components::OpenGL {
|
||||
|
||||
struct Texture {
|
||||
MM::OpenGL::Texture::handle tex;
|
||||
};
|
||||
|
||||
} // MM::Components::OpenGL
|
||||
|
73
framework/opengl_primitives/src/mm/opengl/fbo_builder.cpp
Normal file
73
framework/opengl_primitives/src/mm/opengl/fbo_builder.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "./fbo_builder.hpp"
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
FBOBuilder::FBOBuilder(void) {
|
||||
}
|
||||
|
||||
FBOBuilder::~FBOBuilder(void) {
|
||||
}
|
||||
|
||||
FBOBuilder FBOBuilder::start(void) {
|
||||
FBOBuilder fbob{};
|
||||
|
||||
fbob._fbo.reset(new FrameBufferObject());
|
||||
fbob._fbo->bind(fbob._currTarget);
|
||||
|
||||
return fbob;
|
||||
}
|
||||
|
||||
std::shared_ptr<FrameBufferObject> FBOBuilder::finish(void) {
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
|
||||
return _fbo;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FBOBuilder& FBOBuilder::setTarget(FrameBufferObject::Target target) {
|
||||
_currTarget = target;
|
||||
_fbo->bind(target);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FBOBuilder& FBOBuilder::attachTexture(std::shared_ptr<Texture> tex, GLuint attachment_type) {
|
||||
GLenum target;
|
||||
switch (_currTarget) {
|
||||
case FrameBufferObject::Target::RW:
|
||||
target = GL_FRAMEBUFFER;
|
||||
break;
|
||||
case FrameBufferObject::Target::R:
|
||||
target = GL_READ_FRAMEBUFFER;
|
||||
break;
|
||||
case FrameBufferObject::Target::W:
|
||||
target = GL_DRAW_FRAMEBUFFER;
|
||||
break;
|
||||
}
|
||||
|
||||
//glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->getHandle(), 0);
|
||||
glFramebufferTexture2D(target, attachment_type, GL_TEXTURE_2D, tex->getHandle(), 0);
|
||||
_fbo->_texAttachments.push_back(tex); // keep a ref at the fbo
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FBOBuilder& FBOBuilder::setResize(bool enable) {
|
||||
_fbo->_resize = enable;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FBOBuilder& FBOBuilder::setResizeFactors(float width, float height) {
|
||||
assert(width > 0.f);
|
||||
assert(height > 0.f);
|
||||
|
||||
_fbo->_resize_factor_width = width;
|
||||
_fbo->_resize_factor_height = height;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
34
framework/opengl_primitives/src/mm/opengl/fbo_builder.hpp
Normal file
34
framework/opengl_primitives/src/mm/opengl/fbo_builder.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "./frame_buffer_object.hpp"
|
||||
|
||||
#include "./texture.hpp"
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class FBOBuilder {
|
||||
private:
|
||||
std::shared_ptr<FrameBufferObject> _fbo;
|
||||
FrameBufferObject::Target _currTarget = FrameBufferObject::Target::RW;
|
||||
|
||||
private:
|
||||
FBOBuilder(void);
|
||||
|
||||
public:
|
||||
~FBOBuilder(void);
|
||||
FBOBuilder& operator=(FBOBuilder&) = delete;
|
||||
|
||||
static FBOBuilder start(void);
|
||||
std::shared_ptr<FrameBufferObject> finish(void);
|
||||
|
||||
FBOBuilder& setTarget(FrameBufferObject::Target target);
|
||||
|
||||
FBOBuilder& attachTexture(std::shared_ptr<Texture> tex, GLuint attachment_type = GL_COLOR_ATTACHMENT0);
|
||||
FBOBuilder& setResize(bool enable = true);
|
||||
FBOBuilder& setResizeFactors(float width = 1.f, float height = 1.f);
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,36 @@
|
||||
#include "./frame_buffer_object.hpp"
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
FrameBufferObject::FrameBufferObject(void) {
|
||||
glGenFramebuffers(1, &_fboID);
|
||||
}
|
||||
|
||||
FrameBufferObject::~FrameBufferObject(void) {
|
||||
glDeleteFramebuffers(1, &_fboID);
|
||||
}
|
||||
|
||||
void FrameBufferObject::bind(Target target) const {
|
||||
switch (target) {
|
||||
case Target::RW:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _fboID);
|
||||
break;
|
||||
case Target::R:
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fboID);
|
||||
break;
|
||||
case Target::W:
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fboID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferObject::clear(float r, float g, float b, float a, GLbitfield target_mask) {
|
||||
bind(FrameBufferObject::RW);
|
||||
|
||||
glClearColor(r, g, b, a);
|
||||
//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
glClear(target_mask);
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
namespace MM::Services {
|
||||
class OpenGLRenderer;
|
||||
} // fwd
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class Texture;
|
||||
|
||||
class FrameBufferObject {
|
||||
friend class FBOBuilder;
|
||||
friend class MM::Services::OpenGLRenderer;
|
||||
|
||||
private:
|
||||
uint32_t _fboID;
|
||||
|
||||
bool _resize = true;
|
||||
float _resize_factor_width = 1.f;
|
||||
float _resize_factor_height = 1.f;
|
||||
|
||||
public:
|
||||
std::vector<std::shared_ptr<Texture>> _texAttachments;
|
||||
|
||||
private:
|
||||
FrameBufferObject(void);
|
||||
|
||||
public:
|
||||
~FrameBufferObject(void);
|
||||
|
||||
enum Target {
|
||||
R = 1 << 0,
|
||||
W = 1 << 1,
|
||||
RW = R | W
|
||||
};
|
||||
void bind(Target target) const;
|
||||
//void unbind(void) const;
|
||||
|
||||
void clear(float r, float g, float b, float a, GLbitfield target_mask = GL_COLOR_BUFFER_BIT);
|
||||
};
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,81 @@
|
||||
//
|
||||
// Created by FlaXxy on 25.08.2018.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
//#include <logger.hpp>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
template<typename TInstance>
|
||||
class InstanceBuffer {
|
||||
private:
|
||||
GLuint _handle;
|
||||
size_t _size;
|
||||
|
||||
public:
|
||||
explicit InstanceBuffer(void) : _handle(0), _size(0) {
|
||||
glGenBuffers(1, &_handle);
|
||||
}
|
||||
|
||||
~InstanceBuffer(void) {
|
||||
glDeleteBuffers(1, &_handle);
|
||||
}
|
||||
|
||||
void bind(GLenum target = GL_ARRAY_BUFFER) const {
|
||||
glBindBuffer(target, _handle);
|
||||
}
|
||||
|
||||
void unbind(GLenum target = GL_ARRAY_BUFFER) const {
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
|
||||
void resize(size_t size, GLenum usage) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _handle);
|
||||
glBufferData(GL_ARRAY_BUFFER, size * sizeof(TInstance), nullptr, usage);
|
||||
_size = size;
|
||||
}
|
||||
|
||||
size_t getSize(void) const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
TInstance* map(size_t size, GLenum usage = GL_DYNAMIC_DRAW, bool shrink = false) {
|
||||
if (size > _size || (shrink && (size < _size)))
|
||||
resize(size, usage);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _handle);
|
||||
|
||||
auto* res = static_cast<TInstance*>(
|
||||
glMapBufferRange(
|
||||
GL_ARRAY_BUFFER,
|
||||
0,
|
||||
size * sizeof(TInstance),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT
|
||||
)
|
||||
);
|
||||
//auto* res = static_cast<TInstance*>(
|
||||
//glMapBuffer(
|
||||
//GL_ARRAY_BUFFER,
|
||||
//GL_WRITE_ONLY
|
||||
//)
|
||||
//);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void unmap(void) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER,_handle);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
};
|
||||
} // MM::OpenGL
|
||||
|
211
framework/opengl_primitives/src/mm/opengl/shader.cpp
Normal file
211
framework/opengl_primitives/src/mm/opengl/shader.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
#include "./shader.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_CRIT(...) __LOG_CRIT( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_ERROR(...) __LOG_ERROR("OpenGL", __VA_ARGS__)
|
||||
#define LOG_WARN(...) __LOG_WARN( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_INFO(...) __LOG_INFO( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) __LOG_DEBUG("OpenGL", __VA_ARGS__)
|
||||
#define LOG_TRACE(...) __LOG_TRACE("OpenGL", __VA_ARGS__)
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
Shader::Shader(uint32_t rendererID) : _rendererID(rendererID) {
|
||||
}
|
||||
|
||||
Shader::~Shader(void) {
|
||||
glDeleteProgram(_rendererID);
|
||||
}
|
||||
|
||||
void Shader::bind(void) const {
|
||||
glUseProgram(_rendererID);
|
||||
}
|
||||
|
||||
void Shader::unbind(void) const {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void Shader::setUniform1i(const std::string& name, int32_t v0) {
|
||||
glUniform1i(getUniformLocation(name), v0);
|
||||
}
|
||||
|
||||
void Shader::setUniform1ui(const std::string& name, uint32_t v0) {
|
||||
glUniform1ui(getUniformLocation(name), v0);
|
||||
}
|
||||
|
||||
void Shader::setUniform2ui(const std::string& name, uint32_t v0, uint32_t v1) {
|
||||
glUniform2ui(getUniformLocation(name), v0, v1);
|
||||
}
|
||||
|
||||
void Shader::setUniform1f(const std::string& name, float v0) {
|
||||
glUniform1f(getUniformLocation(name), v0);
|
||||
}
|
||||
|
||||
void Shader::setUniform3f(const std::string& name, float v0, float v1, float v2) {
|
||||
glUniform3f(getUniformLocation(name), v0, v1, v2);
|
||||
}
|
||||
|
||||
void Shader::setUniform3f(const std::string& name, const glm::vec3& vec) {
|
||||
setUniform3f(name, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
void Shader::setUniform4f(const std::string& name, float v0, float v1, float v2, float v3) {
|
||||
glUniform4f(getUniformLocation(name), v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
void Shader::setUniform4f(const std::string& name, const glm::vec4& vec) {
|
||||
setUniform4f(name, vec.x, vec.y, vec.z, vec.w);
|
||||
}
|
||||
|
||||
void Shader::setUniformMat4f(const std::string& name, const glm::mat4& matrix) {
|
||||
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
|
||||
}
|
||||
|
||||
|
||||
void Shader::setUniform2f(const std::string& name, float v0, float v1) {
|
||||
glUniform2f(getUniformLocation(name), v0, v1);
|
||||
}
|
||||
|
||||
void Shader::setUniform2f(const std::string& name, const glm::vec2& vec) {
|
||||
glUniform2f(getUniformLocation(name), vec.x, vec.y);
|
||||
}
|
||||
|
||||
void Shader::setUniformMat3f(const std::string& name, const glm::mat3& matrix) {
|
||||
glUniformMatrix3fv(getUniformLocation(name), 1, GL_FALSE, &matrix[0][0]);
|
||||
}
|
||||
|
||||
std::string Shader::parse(Engine& engine, const std::string& filePath) {
|
||||
auto& fs = engine.getService<MM::Services::FilesystemService>();
|
||||
|
||||
auto handle = fs.open(filePath.c_str());
|
||||
if (!handle) {
|
||||
// TODO: log error
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string file;
|
||||
fs.readString(handle, file);
|
||||
|
||||
fs.close(handle);
|
||||
return file;
|
||||
}
|
||||
|
||||
uint32_t Shader::compile(uint32_t type, const std::string& source) {
|
||||
uint32_t id = glCreateShader(type);
|
||||
const char* src = source.c_str();
|
||||
|
||||
glShaderSource(id, 1, &src, nullptr);
|
||||
glCompileShader(id);
|
||||
|
||||
int32_t res;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &res);
|
||||
if (res == GL_FALSE) {
|
||||
int length;
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
|
||||
char* msg = (char*) alloca(length * sizeof(char));
|
||||
glGetShaderInfoLog(id, length, &length, msg);
|
||||
LOG_ERROR("failed to compile {} Shader: {}", type == GL_VERTEX_SHADER ? "vertex" : "fragment", msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> Shader::createF(Engine& engine, const char* vertexShaderPath, const char* fragmentShaderPath) {
|
||||
std::string vs = parse(engine, vertexShaderPath);
|
||||
std::string fs = parse(engine, fragmentShaderPath);
|
||||
|
||||
return create(vs, fs);
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> Shader::create(const std::string& vertexShader, const std::string& fragmentShader) {
|
||||
uint32_t vs = compile(GL_VERTEX_SHADER, vertexShader);
|
||||
if (vs == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t fs = compile(GL_FRAGMENT_SHADER, fragmentShader);
|
||||
if (fs == 0) {
|
||||
glDeleteShader(vs);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t program = glCreateProgram();
|
||||
|
||||
|
||||
glAttachShader(program, vs);
|
||||
glAttachShader(program, fs);
|
||||
|
||||
glLinkProgram(program);
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
GLint isLinked = 0;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
|
||||
if (isLinked == GL_FALSE) {
|
||||
GLint maxLength = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
|
||||
// The maxLength includes the NULL character
|
||||
std::vector<GLchar> infoLog(maxLength);
|
||||
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
|
||||
LOG_ERROR("Linking Shader Programs: {}", &infoLog[0]);
|
||||
|
||||
// The program is useless now. So delete it.
|
||||
glDeleteProgram(program);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glValidateProgram(program);
|
||||
GLint isValid = 0;
|
||||
glGetProgramiv(program, GL_VALIDATE_STATUS, &isValid);
|
||||
if (isValid == GL_FALSE) {
|
||||
GLint maxLength = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
|
||||
// The maxLength includes the NULL character
|
||||
std::vector<GLchar> infoLog(maxLength);
|
||||
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
|
||||
LOG_ERROR("Validating Shader Programs: {}", &infoLog[0]);
|
||||
|
||||
// The program is useless now. So delete it.
|
||||
glDeleteProgram(program);
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
//todo: make some check if linking and validating actually worked
|
||||
return std::shared_ptr<Shader>(new Shader(program));
|
||||
}
|
||||
|
||||
int32_t Shader::getUniformLocation(const std::string& name) {
|
||||
if (_uniformLocationCache.find(name) != _uniformLocationCache.end()) {
|
||||
return _uniformLocationCache[name];
|
||||
}
|
||||
|
||||
int32_t location = glGetUniformLocation(_rendererID, name.c_str());
|
||||
|
||||
if (location == -1) {
|
||||
LOG_WARN("uniform '{}' doesn't exist! (hint: the compiler removes unused variables)", name);
|
||||
}
|
||||
|
||||
_uniformLocationCache[name] = location;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
int32_t Shader::getAttribLocation(const std::string& name) {
|
||||
int32_t location = glGetAttribLocation(_rendererID, name.c_str());
|
||||
|
||||
if (location == -1) {
|
||||
LOG_WARN("attrib '{}' doesn't exist! (hint: the compiler removes unused variables)", name);
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
69
framework/opengl_primitives/src/mm/opengl/shader.hpp
Normal file
69
framework/opengl_primitives/src/mm/opengl/shader.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
//#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/mat3x3.hpp>
|
||||
|
||||
// fwd
|
||||
namespace MM {
|
||||
class Engine;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class Shader {
|
||||
private:
|
||||
uint32_t _rendererID;
|
||||
std::unordered_map<std::string, int32_t> _uniformLocationCache;
|
||||
|
||||
public:
|
||||
~Shader(void);
|
||||
|
||||
void bind(void) const;
|
||||
void unbind(void) const;
|
||||
|
||||
// set uniforms
|
||||
void setUniform1i(const std::string& name, int32_t v0);
|
||||
|
||||
void setUniform1ui(const std::string& name, uint32_t v0);
|
||||
void setUniform2ui(const std::string& name, uint32_t v0, uint32_t v1);
|
||||
|
||||
void setUniform1f(const std::string& name, float v0);
|
||||
void setUniform2f(const std::string& name, float v0, float v1);
|
||||
void setUniform2f(const std::string& name, const glm::vec2& vec);
|
||||
void setUniform3f(const std::string& name, float v0, float v1, float v2);
|
||||
void setUniform3f(const std::string& name, const glm::vec3& vec);
|
||||
void setUniform4f(const std::string& name, float v0, float v1, float v2, float v3);
|
||||
void setUniform4f(const std::string& name, const glm::vec4& vec);
|
||||
|
||||
void setUniformMat4f(const std::string& name, const glm::mat4& matrix);
|
||||
void setUniformMat3f(const std::string& name, const glm::mat3& matrix);
|
||||
|
||||
static std::shared_ptr<Shader> createF(Engine& engine, const char* vertexShaderPath, const char* fragmentShaderPath);
|
||||
static std::shared_ptr<Shader> create(const std::string& vertexShader, const std::string& fragmentShader);
|
||||
|
||||
private:
|
||||
explicit Shader(uint32_t rendererID);
|
||||
|
||||
static std::string parse(Engine& engine, const std::string& filePath);
|
||||
static uint32_t compile(uint32_t type, const std::string& source);
|
||||
|
||||
public:
|
||||
int32_t getUniformLocation(const std::string& name);
|
||||
int32_t getAttribLocation(const std::string& name);
|
||||
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
17
framework/opengl_primitives/src/mm/opengl/spritesheet.hpp
Normal file
17
framework/opengl_primitives/src/mm/opengl/spritesheet.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "./texture.hpp"
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
// a SpriteSheet is a texture divided evenly into a Grid
|
||||
struct SpriteSheet {
|
||||
MM::OpenGL::Texture::handle tex = nullptr;
|
||||
struct {
|
||||
uint32_t x = 1;
|
||||
uint32_t y = 1;
|
||||
} tile_count;
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
61
framework/opengl_primitives/src/mm/opengl/texture.cpp
Normal file
61
framework/opengl_primitives/src/mm/opengl/texture.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "./texture.hpp"
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
uint32_t Texture::getHandle(void) const {
|
||||
return _handle;
|
||||
}
|
||||
|
||||
Texture::Texture(
|
||||
uint32_t handle,
|
||||
int32_t width, int32_t height,
|
||||
int32_t internalFormat, int32_t format, int32_t type
|
||||
) : _handle(handle), width(width), height(height),
|
||||
_internalFormat(internalFormat), _format(format), _type(type) {}
|
||||
|
||||
Texture::~Texture(void) {
|
||||
glDeleteTextures(1, &_handle);
|
||||
}
|
||||
|
||||
void Texture::unbind(void) const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void Texture::bind(uint32_t slot) const {
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
glBindTexture(GL_TEXTURE_2D, _handle);
|
||||
}
|
||||
|
||||
void Texture::resize(int32_t new_width, int32_t new_height) {
|
||||
// if (glTexImage2D == true)
|
||||
glBindTexture(GL_TEXTURE_2D, _handle);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat, new_width, new_height, 0, _format, _type, NULL);
|
||||
|
||||
// HACK: super dirty
|
||||
*(const_cast<int32_t*>(&width)) = new_width;
|
||||
*(const_cast<int32_t*>(&height)) = new_height;
|
||||
}
|
||||
|
||||
Texture::handle Texture::createEmpty(int32_t internalFormat, int32_t width, int32_t height, int32_t format, int32_t type) {
|
||||
uint32_t id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return handle(new Texture(id, width, height, internalFormat, format, type));
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
49
framework/opengl_primitives/src/mm/opengl/texture.hpp
Normal file
49
framework/opengl_primitives/src/mm/opengl/texture.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mm/resource_manager.hpp>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
struct TextureLoaderFile;
|
||||
struct TextureLoaderConstBuffer;
|
||||
|
||||
class Texture {
|
||||
private:
|
||||
uint32_t const _handle;
|
||||
|
||||
private:
|
||||
friend struct TextureLoaderFile;
|
||||
friend struct TextureLoaderConstBuffer;
|
||||
|
||||
Texture(
|
||||
uint32_t handle,
|
||||
int32_t width, int32_t height,
|
||||
int32_t internalFormat, int32_t format, int32_t type
|
||||
);
|
||||
|
||||
public:
|
||||
using handle = std::shared_ptr<Texture>;
|
||||
|
||||
int32_t const width;
|
||||
int32_t const height;
|
||||
//int32_t const bpp; // bits per pixel
|
||||
private:
|
||||
int32_t const _internalFormat;
|
||||
int32_t const _format;
|
||||
int32_t const _type;
|
||||
|
||||
public:
|
||||
~Texture();
|
||||
|
||||
uint32_t getHandle(void) const;
|
||||
|
||||
void bind(uint32_t slot) const;
|
||||
void unbind(void) const;
|
||||
|
||||
void resize(int32_t new_width, int32_t new_height);
|
||||
|
||||
static handle createEmpty(int32_t internalFormat, int32_t width, int32_t height, int32_t format, int32_t type);
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
133
framework/opengl_primitives/src/mm/opengl/texture_loader.cpp
Normal file
133
framework/opengl_primitives/src/mm/opengl/texture_loader.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
#include "./texture_loader.hpp"
|
||||
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <mm/services/filesystem.hpp>
|
||||
#include <mm/engine.hpp>
|
||||
|
||||
#include <mm/logger.hpp>
|
||||
#define LOG_CRIT(...) __LOG_CRIT( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_ERROR(...) __LOG_ERROR("OpenGL", __VA_ARGS__)
|
||||
#define LOG_WARN(...) __LOG_WARN( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_INFO(...) __LOG_INFO( "OpenGL", __VA_ARGS__)
|
||||
#define LOG_DEBUG(...) __LOG_DEBUG("OpenGL", __VA_ARGS__)
|
||||
#define LOG_TRACE(...) __LOG_TRACE("OpenGL", __VA_ARGS__)
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
std::shared_ptr<Texture> TextureLoaderFile::load(Engine& engine, const std::string& path) const {
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
int width, height, bpp;
|
||||
uint32_t handle;
|
||||
|
||||
//auto buffer = stbi_load(path.c_str(), &width, &height, &bpp, 4);
|
||||
|
||||
auto* fs = engine.tryService<MM::Services::FilesystemService>();
|
||||
|
||||
struct cb_data_t {
|
||||
MM::Services::FilesystemService* fs;
|
||||
MM::Services::FilesystemService::fs_file_t file;
|
||||
};
|
||||
|
||||
stbi_io_callbacks io_cb {
|
||||
[](void* user, char* data, int size) -> int {
|
||||
cb_data_t* fs_d = (cb_data_t*)user;
|
||||
|
||||
return (int)fs_d->fs->read(fs_d->file, data, size);
|
||||
},
|
||||
|
||||
[](void* user, int n) -> void {
|
||||
cb_data_t* fs_d = (cb_data_t*)user;
|
||||
|
||||
fs_d->fs->seek(fs_d->file, fs_d->fs->tell(fs_d->file) + n);
|
||||
},
|
||||
|
||||
[](void* user) -> int {
|
||||
cb_data_t* fs_d = (cb_data_t*)user;
|
||||
|
||||
return (int)fs_d->fs->eof(fs_d->file);
|
||||
}
|
||||
};
|
||||
|
||||
auto file = fs->open(path.c_str());
|
||||
if (!file) {
|
||||
LOG_ERROR("opening texture '{}'", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//auto* buffer = stbi_load_from_callbacks(&io_cb, file, &width, &height, &bpp, 4);
|
||||
cb_data_t data {fs, file};
|
||||
auto* buffer = stbi_load_from_callbacks(&io_cb, &data, &width, &height, &bpp, 4);
|
||||
|
||||
fs->close(file);
|
||||
|
||||
if (buffer == nullptr) {
|
||||
LOG_ERROR("stbi error opening texture '{}'", path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glGenTextures(1, &handle);
|
||||
glBindTexture(GL_TEXTURE_2D, handle);
|
||||
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
stbi_image_free(buffer);
|
||||
|
||||
return std::shared_ptr<Texture>(new Texture(handle, width, height, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE));
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> TextureLoaderConstBuffer::load(const uint8_t* data, size_t size) const {
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
|
||||
int width, height, bpp;
|
||||
uint32_t handle;
|
||||
|
||||
auto* buffer = stbi_load_from_memory(data, size, &width, &height, &bpp, 4);
|
||||
|
||||
if (buffer == nullptr) {
|
||||
LOG_ERROR("stbi error opening memory texture");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glGenTextures(1, &handle);
|
||||
glBindTexture(GL_TEXTURE_2D, handle);
|
||||
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
stbi_image_free(buffer);
|
||||
|
||||
return std::shared_ptr<Texture>(new Texture(handle, width, height, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE));
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
29
framework/opengl_primitives/src/mm/opengl/texture_loader.hpp
Normal file
29
framework/opengl_primitives/src/mm/opengl/texture_loader.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "./texture.hpp"
|
||||
#include <utility>
|
||||
|
||||
// fwd
|
||||
namespace MM {
|
||||
class Engine;
|
||||
}
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
struct TextureLoaderFile final {
|
||||
std::shared_ptr<Texture> load(Engine& engine, const std::string& path) const;
|
||||
};
|
||||
|
||||
struct TextureLoaderConstBuffer final {
|
||||
std::shared_ptr<Texture> load(const uint8_t* data, size_t size) const;
|
||||
};
|
||||
|
||||
struct TextureLoaderEmpty final {
|
||||
template<typename... Args>
|
||||
std::shared_ptr<Texture> load(Args&& ... args) const {
|
||||
return Texture::createEmpty(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,28 @@
|
||||
#include "./vertex_array_object.hpp"
|
||||
|
||||
#ifdef MM_OPENGL_3_GLES
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <glad/glad.h>
|
||||
#endif
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
VertexArrayObject::VertexArrayObject(void) {
|
||||
glGenVertexArrays(1, &_rendererID);
|
||||
}
|
||||
|
||||
VertexArrayObject::~VertexArrayObject(void) {
|
||||
glDeleteVertexArrays(1, &_rendererID);
|
||||
}
|
||||
|
||||
void VertexArrayObject::bind(void) const {
|
||||
glBindVertexArray(_rendererID);
|
||||
}
|
||||
|
||||
void VertexArrayObject::unbind(void) const {
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
} // MM::OpenGL
|
||||
|
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace MM::OpenGL {
|
||||
|
||||
class VertexArrayObject {
|
||||
private:
|
||||
uint32_t _rendererID;
|
||||
|
||||
public:
|
||||
VertexArrayObject(void);
|
||||
~VertexArrayObject(void);
|
||||
|
||||
void bind(void) const;
|
||||
void unbind(void) const;
|
||||
};
|
||||
|
||||
} // MM::OpenGL
|
||||
|
Reference in New Issue
Block a user