Skip to content
Snippets Groups Projects
Commit a043ec94 authored by BATON Theau's avatar BATON Theau
Browse files

Initial commit

parents
No related branches found
No related tags found
1 merge request!1Mergin master into main
Showing
with 1063 additions and 0 deletions
*.vscode
*.o
*.obj
*.pdb
*.a
*.dll
*.so
*.lib
*.exe
*.git
build/*
include/*
library/*
vcpkg_installed/*
old/*
\ No newline at end of file
cmake_minimum_required(VERSION 3.1)
#==============================================================
# Configuration
#==============================================================
set(PROJECT_NAME "Main")
set(EXECUTABLE_NAME "Main")
set(CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD ${CXX_STANDARD})
if (MSVC)
add_compile_options(/EHsc)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
#=====================================
# Options
#=====================================
if(WIN32)
option(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/vcpkg/scripts/buildsystems/vcpkg.cmake")
elseif(UNIX)
option(CMAKE_TOOLCHAIN_FILE "/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake")
endif()
#==============================================================
# Sources
#==============================================================
set(SOURCES ${CMAKE_SOURCE_DIR}/source/)
set(LIBRARY ${CMAKE_SOURCE_DIR}/library/)
set(INCLUDE ${CMAKE_SOURCE_DIR}/include/)
set(VCPK_INCLUDE ${CMAKE_SOURCE_DIR}/vcpkg_installed/*/include)
set(VCPK_INCLUDE ${CMAKE_SOURCE_DIR}/vcpkg_installed/*/lib)
#==============================================================
# Build
#==============================================================
project(${PROJECT_NAME})
set(CURRENT_TARGET ${EXECUTABLE_NAME})
add_executable(${CURRENT_TARGET})
foreach(dir ${SOURCES})
add_subdirectory(${dir})
endforeach()
set_property(TARGET ${CURRENT_TARGET} PROPERTY RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_SOURCE_DIR}>)
#==============================================================
# Linking
#==============================================================
target_include_directories(${CURRENT_TARGET} PRIVATE ${INCLUDE})
find_package(glfw3 REQUIRED)
find_package(GLEW REQUIRED)
find_package(glm CONFIG REQUIRED)
find_package(imgui REQUIRED)
target_link_libraries(${CURRENT_TARGET} PRIVATE glfw)
target_link_libraries(${CURRENT_TARGET} PRIVATE GLEW::GLEW)
target_link_libraries(${CURRENT_TARGET} PRIVATE glm::glm-header-only)
target_link_libraries(${CURRENT_TARGET} PRIVATE imgui::imgui)
# Projet FIG
## Building
Debug mode :
```shell
cmake --build ./build
```
Release Mode :
```shell
cmake --build ./build --config Release
```
\ No newline at end of file
target_include_directories(${CURRENT_TARGET} PRIVATE .)
file(GLOB_RECURSE SOURCE ./**.cpp)
target_sources(${CURRENT_TARGET} PRIVATE ${SOURCE})
\ No newline at end of file
#pragma once
#include "back/buffers/ElementBuffer.hpp"
#include "back/buffers/FrameBuffer.hpp"
#include "back/buffers/VerticeBuffer.hpp"
#include "back/buffers/VertexArray.hpp"
#include "back/buffers/UniformeBuffer.hpp"
#include "back/cameras/Target.hpp"
#include "back/cameras/View.hpp"
#include "back/cameras/Walkaround.hpp"
#include "back/geometry/Geometry.hpp"
#include "back/geometry/Transform.hpp"
#include "back/shaders/Program.hpp"
#include "back/shaders/Source.hpp"
#include "back/shaders/UniformObject.hpp"
#include "back/textures/Shared_Material.hpp"
\ No newline at end of file
#pragma once
#include <GL/glew.h>
namespace megu {
class Buffer {
public:
virtual void bind() const = 0;
virtual void unbind() const = 0;
virtual GLuint identifier() const = 0;
};
}
\ No newline at end of file
#include "DynamicBuffer.cpp"
namespace megu {
template class DynamicBuffer<float, GL_ARRAY_BUFFER>;
template class DynamicBuffer<unsigned int, GL_ELEMENT_ARRAY_BUFFER>;
}
\ No newline at end of file
#include "DynamicBuffer.hpp"
#include <GL/glew.h>
#include <exception>
#include <stdexcept>
#include <iostream>
namespace megu {
template <typename T, uint32_t Y>
DynamicBuffer<T,Y>::DynamicBuffer(size_t size, size_t array_size)
: _max_size(size),_size(array_size) {
}
template <typename T, uint32_t Y>
size_t DynamicBuffer<T,Y>::size() const {
return this->_size;
}
template <typename T, uint32_t Y>
size_t DynamicBuffer<T,Y>::max_size() const {
return this->_max_size;
}
template <typename T, uint32_t Y>
size_t DynamicBuffer<T,Y>::memory_size() const {
return this->_size * sizeof(T);
}
template <typename T, uint32_t Y>
size_t DynamicBuffer<T,Y>::max_memory_size() const {
return this->_max_size * sizeof(T);
}
template <typename T, uint32_t Y>
bool DynamicBuffer<T,Y>::empty() const {
return this->_size == 0;
}
template <typename T, uint32_t Y>
bool DynamicBuffer<T,Y>::full() const {
return this->_size == this->_max_size;
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::set(const std::vector<T> & vertices) {
this->_max_size = vertices.size();
this->_size = vertices.size();
this->generate(vertices);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::insert(const std::vector<T> & vertices, size_t pos) {
if(this->_size + vertices.size() > this->_max_size) {
std::vector<T> data = this->extract();
data.insert(data.begin() + pos, vertices.begin(), vertices.end());
this->set(data);
}
else {
if(this->identifier() != 0) {
this->bind();
uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y, GL_READ_WRITE));
if(pos < this->_size) {
memmove(writer + ((pos + vertices.size()) * sizeof(T)), writer + (pos * sizeof(T)), (this->_size-pos) * sizeof(T));
}
memmove(writer + (pos * sizeof(T)), std::vector<T>(vertices).data(), vertices.size() * sizeof(T));
glUnmapBuffer(Y);
this->_size += vertices.size();
}
else {
this->generate(vertices);
}
}
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::replace(const std::vector<T> & vertices, size_t pos) {
if(this->empty()) {
throw std::range_error("Buffer is empty.");
}
if(pos + vertices.size() > this->_size) {
throw std::overflow_error("Cannot replace datas out of buffer.");
}
this->bind();
glBufferSubData(Y, pos * sizeof(T),vertices.size() * sizeof(T), std::vector<T>(vertices).data());
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::erase(size_t from, size_t to) {
if(this->empty()) {
throw std::range_error("Buffer is empty.");
}
if(this->_size - to - from < 0) {
throw std::underflow_error("Cannot erase datas out of buffer.");
}
this->bind();
uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y, GL_READ_WRITE));
memmove(writer + (from * sizeof(T)), writer + ((to+1) * sizeof(T)), (this->_size-to) * sizeof(T));
glUnmapBuffer(Y);
this->_size -= (to + 1 - from);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::merge(const DynamicBuffer<T,Y> & vbo, size_t pos) {
if(this->_size + vbo._size > this->_max_size) {
throw std::overflow_error("Cannot add datas out of buffer.");
}
if(pos < this->_size) {
this->bind();
uint8_t * writer = static_cast<uint8_t *>(glMapBuffer(Y,GL_READ_WRITE));
memmove(writer + (pos + vbo._size) * sizeof(T), writer + (pos * sizeof(T)), (this->_size-pos) * sizeof(T));
glUnmapBuffer(Y);
}
this->_size += vbo._size;
glBindBuffer(GL_COPY_READ_BUFFER, vbo.identifier());
glBindBuffer(GL_COPY_WRITE_BUFFER, this->identifier());
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, pos * sizeof(T),vbo._size * sizeof(T));
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::resize(size_t max_size) {
if(this->_size > max_size) {
throw std::overflow_error("Cannot set a new max size that is greater than current size");
}
std::vector<T> save = this->extract();
this->_max_size = max_size;
this->generate(save);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::push_back(const std::vector<T> & vertices) {
this->insert(vertices, this->_size);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::push_front(const std::vector<T> & vertices) {
this->insert(vertices, 0);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::pop_back(size_t offset) {
if(offset > this->_size) {
throw std::underflow_error("Cannot erase datas out of buffer.");
}
if(offset > 0) {
this->erase(this->_size-offset+1, this->_size);
}
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::pop_front(size_t offset) {
if(offset > this->_size) {
throw std::overflow_error("Cannot add datas out of buffer.");
}
if(offset > 0) {
this->erase(0, offset-1);
}
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::regenerate(size_t max_size) {
this->_max_size = max_size;
this->generate({});
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::reset(const std::vector<T> & data) {
this->set(data);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::clear() {
this->generate({});
}
template <typename T, uint32_t Y>
T DynamicBuffer<T,Y>::back() const {
if(this->empty()) {
throw std::underflow_error("Cannot get data from empty buffer.");
}
return this->operator[](0);
}
template <typename T, uint32_t Y>
T DynamicBuffer<T,Y>::front() const {
if(this->empty()) {
throw std::underflow_error("Cannot get data from empty buffer.");
}
return this->operator[](this->_size-1);
}
template <typename T, uint32_t Y>
T DynamicBuffer<T,Y>::at(size_t index) const {
return this->operator[](index);
}
template <typename T, uint32_t Y>
std::vector<T> DynamicBuffer<T,Y>::extract() const {
return this->extract(0, this->_size);
}
template <typename T, uint32_t Y>
std::vector<T> DynamicBuffer<T,Y>::extract(size_t from,size_t to) const {
if(to > this->_size) {
throw std::overflow_error("Cannot extract datas out of buffer.");
}
this->bind();
void * writer = glMapBuffer(Y, GL_WRITE_ONLY);
std::vector<T> data{static_cast<T *>(writer) + from, static_cast<T *>(writer) + from + (to - from)};
glUnmapBuffer(Y);
return data;
}
template <typename T, uint32_t Y>
T DynamicBuffer<T,Y>::operator[](size_t index) const {
return this->extract(index,index)[0];
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::modify(std::function<void(void *)> modif) {
this->bind();
modif(glMapBuffer(Y, GL_READ_WRITE));
glUnmapBuffer(Y);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::operator()(std::function<void(void *)> modif) {
this->modify(modif);
}
template <typename T, uint32_t Y>
void DynamicBuffer<T,Y>::operator<<(const DynamicBuffer<T,Y> & buffer) {
this->merge(buffer);
}
}
\ No newline at end of file
#pragma once
#include "Buffer.hpp"
#include <stdint.h>
#include <vector>
#include <list>
#include <functional>
namespace megu {
template <typename T, uint32_t Y>
class DynamicBuffer : public Buffer {
private:
size_t _max_size;
size_t _size;
public:
DynamicBuffer() = delete;
DynamicBuffer(size_t, size_t=0);
DynamicBuffer(const DynamicBuffer &) = delete;
virtual void generate(const std::vector<T> &) = 0;
size_t size() const;
size_t max_size() const;
size_t memory_size() const;
size_t max_memory_size() const;
bool empty() const;
bool full() const;
void set(const std::vector<T> &);
void insert(const std::vector<T> &, size_t pos);
void replace(const std::vector<T> &, size_t pos);
void erase(size_t from,size_t to);
void merge(const DynamicBuffer<T,Y> &, size_t pos=0);
void push_back(const std::vector<T> &);
void push_front(const std::vector<T> &);
void regenerate(size_t max_size);
void reset(const std::vector<T> &);
void clear();
void resize(size_t max_size);
void pop_back(size_t offset=1);
void pop_front(size_t offset=1);
T back() const;
T front() const;
T at(size_t index) const;
std::vector<T> extract() const;
std::vector<T> extract(size_t from,size_t to) const;
T operator[](size_t index) const;
void modify(std::function<void(void *)>);
void operator()(std::function<void(void *)>);
void operator<<(const DynamicBuffer<T,Y> &);
};
}
\ No newline at end of file
#include "ElementBuffer.hpp"
namespace megu {
ElementBuffer::ElementBuffer(const VertexArray & vao,size_t size,uint32_t mode)
: DynamicBuffer(size),_vao(&vao),_id(0),_mode(mode) {
this->generate({});
}
ElementBuffer::ElementBuffer(const VertexArray & vao,const std::vector<unsigned int> & indices,uint32_t mode)
: DynamicBuffer(indices.size(),indices.size()),_vao(&vao),_id(0),_mode(mode) {
this->generate(indices);
}
ElementBuffer::~ElementBuffer() {
this->unbind();
glDeleteBuffers(1,&this->_id);
}
GLuint ElementBuffer::identifier() const {
return this->_id;
}
void ElementBuffer::bind() const {
if(this->_id != 0) {
this->_vao->bind();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->_id);
}
}
void ElementBuffer::unbind() const {
GLint ebo = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER, &ebo);
if(static_cast<GLuint>(ebo) == this->_id) {
this->_vao->unbind();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
void ElementBuffer::generate(const std::vector<unsigned int> & vertices) {
this->_vao->bind();
if(this->_id != 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDeleteBuffers(1,&this->_id);
}
glGenBuffers(1,&this->_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,this->_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,this->max_size()*sizeof(unsigned int),vertices.size() == 0 ? NULL : std::vector<unsigned int>(vertices).data(),this->_mode);
}
bool ElementBuffer::operator==(const ElementBuffer & ebo) const {
return this->_id == ebo._id;
}
bool ElementBuffer::operator!=(const ElementBuffer & ebo) const {
return this->_id != ebo._id;
}
bool ElementBuffer::operator>(const ElementBuffer & ebo) const {
return this->_id > ebo._id;
}
bool ElementBuffer::operator>=(const ElementBuffer & ebo) const {
return this->_id >= ebo._id;
}
bool ElementBuffer::operator<(const ElementBuffer & ebo) const {
return this->_id < ebo._id;
}
bool ElementBuffer::operator<=(const ElementBuffer & ebo) const {
return this->_id <= ebo._id;
}
std::strong_ordering ElementBuffer::operator<=>(const ElementBuffer & ebo) const {
return this->_id <=> ebo._id;
}
ElementBuffer & operator<<(ElementBuffer & ebo, const std::initializer_list<unsigned int> & data) {
ebo.push_back(data);
return ebo;
}
ElementBuffer & operator<<(ElementBuffer & ebo, const std::vector<unsigned int> & data) {
ebo.push_back(data);
return ebo;
}
}
\ No newline at end of file
#pragma once
#include <compare>
#include "DynamicBuffer.hpp"
#include "VertexArray.hpp"
namespace megu {
class ElementBuffer : public DynamicBuffer<unsigned int, GL_ELEMENT_ARRAY_BUFFER> {
private:
const VertexArray * _vao;
GLuint _id;
GLuint _mode;
public:
ElementBuffer() = delete;
ElementBuffer(const VertexArray & vao,size_t size=1024,uint32_t mode=GL_DYNAMIC_DRAW);
ElementBuffer(const VertexArray & vao,const std::vector<unsigned int> & indice,uint32_t mode=GL_DYNAMIC_DRAW);
ElementBuffer(const ElementBuffer &) = delete;
virtual ~ElementBuffer();
virtual inline GLuint identifier() const;
virtual void bind() const;
virtual void unbind() const;
virtual void generate(const std::vector<unsigned int> &);
inline bool operator==(const ElementBuffer &) const;
inline bool operator!=(const ElementBuffer &) const;
inline bool operator<=(const ElementBuffer &) const;
inline bool operator>=(const ElementBuffer &) const;
inline bool operator<(const ElementBuffer &) const;
inline bool operator>(const ElementBuffer &) const;
inline std::strong_ordering operator<=>(const ElementBuffer &) const;
friend ElementBuffer & operator<<(ElementBuffer &, const std::initializer_list<unsigned int> &);
friend ElementBuffer & operator<<(ElementBuffer &, const std::vector<unsigned int> &);
};
}
\ No newline at end of file
#include "FrameBuffer.hpp"
#include <iostream>
#include "../../errors/OpenGL_Error.hpp"
namespace megu {
FrameBuffer::FrameBuffer(GLuint width, GLuint height)
: _id(0), _rbo_id(0), _texture() {
glGenFramebuffers(1, &this->_id);
glBindFramebuffer(GL_FRAMEBUFFER, this->_id);
this->_texture.store(width, height, NULL, Texture::Format::RGB);
this->_texture.setSmoothing(false);
this->_texture.setWraping(Texture::Wraping::CLAMP_TO_EDGE, Texture::Axis::S | Texture::Axis::T);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->_texture.identifier(), 0);
glGenRenderbuffers(1, &this->_rbo_id);
glBindRenderbuffer(GL_RENDERBUFFER, this->_rbo_id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->_rbo_id);
if(!this->usable()) {
std::cerr << "Incomplete FrameBuffer." << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
FrameBuffer::~FrameBuffer() {
glDeleteRenderbuffers(1, &this->_rbo_id);
glDeleteFramebuffers(1, &this->_id);
}
bool FrameBuffer::usable() const {
this->bind();
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}
void FrameBuffer::bind() const {
glBindFramebuffer(GL_FRAMEBUFFER, this->_id);
}
void FrameBuffer::unbind() const {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::BindDefaultFrameBuffer() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
\ No newline at end of file
#pragma once
#include "Buffer.hpp"
#include "../textures/Texture.hpp"
namespace megu {
class FrameBuffer : public Buffer {
private:
GLuint _id;
GLuint _rbo_id;
Texture _texture;
public:
FrameBuffer() = delete;
FrameBuffer(GLuint width, GLuint height);
virtual ~FrameBuffer();
inline const Texture & texture() const {return this->_texture;}
GLuint rbo_identifier() const {return this->_rbo_id;}
inline virtual GLuint identifier() const {return this->_id;}
bool usable() const;
virtual void bind() const;
virtual void unbind() const;
static void BindDefaultFrameBuffer();
};
}
\ No newline at end of file
#pragma once
#include <list>
#include <numeric>
#include <stdint.h>
namespace megu {
using Layout = std::list<uint8_t>;
using Layout_Initializer = std::initializer_list<uint8_t>;
namespace layout {
inline size_t weight(const Layout & layout) {
return std::accumulate(layout.begin(), layout.end(), 0);
}
enum Value : unsigned char {
POSITION = 3,
FLAT = 2,
COLOR = 3,
NORMAL = 3,
TEXTURE = 2,
BORDER = 2,
ID = 1,
};
}
}
\ No newline at end of file
#pragma once
#include "Buffer.hpp"
#include <optional>
#include <string>
#include <map>
#include "../shaders/Program.hpp"
namespace megu {
template <class T>
class UniformeBuffer : public Buffer {
private:
T * _data;
GLuint _id;
std::map<const Program *, GLuint> _programs;
public:
UniformeBuffer(T * = nullptr);
virtual ~UniformeBuffer();
inline GLuint index(const Program & program) const {return this->_programs.at(&program);}
inline std::optional<T> data() const {this->_data != nullptr ? std::optional<T>(*this->_data) : std::optional<T>();}
void setData(T *);
void attach(const std::string &, const Program &);
inline virtual GLuint identifier() const {return this->_id;}
virtual void bind() const;
virtual void unbind() const;
};
}
#include "UniformeBuffer.tpp"
\ No newline at end of file
#include "UniformeBuffer.hpp"
namespace megu {
template <class T>
UniformeBuffer<T>::UniformeBuffer(T * data)
: _data(data), _id(0) {
glCreateBuffers(1, &this->_id);
glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
glBufferData(GL_UNIFORM_BUFFER, sizeof(T), data, GL_DYNAMIC_DRAW);
}
template <class T>
UniformeBuffer<T>::~UniformeBuffer() {
glDeleteBuffers(1, &this->_id);
}
template <class T>
void UniformeBuffer<T>::setData(T * data) {
this->_data = data;
glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), data);
}
template <class T>
void UniformeBuffer<T>::attach(const std::string & name, const Program & program) {
this->_programs.insert(std::pair<const Program *, GLuint>(&program, 0));
glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
this->_programs[&program] = glGetUniformBlockIndex(program.id(), name.c_str());
glBindBufferBase(GL_UNIFORM_BUFFER, this->_programs[&program], this->_id);
}
template <class T>
void UniformeBuffer<T>::bind() const {
glBindBuffer(GL_UNIFORM_BUFFER, this->_id);
}
template <class T>
void UniformeBuffer<T>::unbind() const {
GLint binded = 0;
glGetIntegerv(GL_UNIFORM_BUFFER_BINDING, &binded);
if(static_cast<GLuint>(binded) == this->_id) {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
}
\ No newline at end of file
#include "VertexArray.hpp"
namespace megu {
VertexArray::VertexArray(bool binded)
: _vao(0) {
glGenVertexArrays(1, &this->_vao);
if(binded) {
this->bind();
}
}
VertexArray::~VertexArray() {
this->unbind();
glDeleteVertexArrays(1,&this->_vao);
}
void VertexArray::bind() const {
if(this->_vao != 0) {
glBindVertexArray(this->_vao);
}
}
void VertexArray::unbind()const {
GLint vao;
glGetIntegerv(GL_ARRAY_BUFFER, &vao);
if(static_cast<GLuint>(vao) == this->_vao) {
glBindVertexArray(0);
}
}
bool VertexArray::operator==(const VertexArray & vao) const {
return this->_vao == vao._vao;
}
bool VertexArray::operator!=(const VertexArray & vao) const {
return this->_vao != vao._vao;
}
bool VertexArray::operator>(const VertexArray & vao) const {
return this->_vao > vao._vao;
}
bool VertexArray::operator>=(const VertexArray & vao) const {
return this->_vao >= vao._vao;
}
bool VertexArray::operator<(const VertexArray & vao) const {
return this->_vao < vao._vao;
}
bool VertexArray::operator<=(const VertexArray & vao) const {
return this->_vao <= vao._vao;
}
std::strong_ordering VertexArray::operator<=>(const VertexArray & vao) const {
return this->_vao <=> vao._vao;
}
}
\ No newline at end of file
#pragma once
#include <compare>
#include <GL/glew.h>
#include "Buffer.hpp"
namespace megu {
class VertexArray : public Buffer {
private:
GLuint _vao;
public:
VertexArray(bool binded=false);
VertexArray(const VertexArray &) = delete;
virtual ~VertexArray();
virtual GLuint identifier() const {return this->_vao;}
virtual void bind() const;
virtual void unbind() const;
bool operator==(const VertexArray &) const;
bool operator!=(const VertexArray &) const;
bool operator<=(const VertexArray &) const;
bool operator>=(const VertexArray &) const;
bool operator<(const VertexArray &) const;
bool operator>(const VertexArray &) const;
std::strong_ordering operator<=>(const VertexArray &) const;
};
}
\ No newline at end of file
#include "VerticeBuffer.hpp"
#include <list>
namespace megu {
VerticeBuffer::VerticeBuffer(const VertexArray & vao,const Layout_Initializer & attributes,size_t size,uint32_t mode)
: DynamicBuffer(size), _vao(&vao), _id(0), _mode(mode), _layout(attributes) {
this->generate({});
}
VerticeBuffer::VerticeBuffer(const VertexArray & vao,const std::vector<float> & vertices, const Layout & attributes,uint32_t mode)
: DynamicBuffer(vertices.size(), vertices.size()), _vao(&vao), _id(0), _mode(mode), _layout(attributes) {
this->generate(vertices);
}
VerticeBuffer::~VerticeBuffer() {
this->unbind();
glDeleteBuffers(1, &this->_id);
}
GLuint VerticeBuffer::identifier() const {
return this->_id;
}
size_t VerticeBuffer::weight() const {
return layout::weight(this->_layout);
}
size_t VerticeBuffer::vertices() const {
return this->size() / this->weight();
}
void VerticeBuffer::bind() const {
if(this->_id != 0) {
this->_vao->bind();
glBindBuffer(GL_ARRAY_BUFFER, this->_id);
}
}
void VerticeBuffer::unbind() const {
GLint vbo = 0;
glGetIntegerv(GL_ARRAY_BUFFER, &vbo);
if(static_cast<GLuint>(vbo) == this->_id) {
this->_vao->unbind();
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
void VerticeBuffer::generate(const std::vector<float> & vertices) {
this->_vao->bind();
if(this->_id != 0) {
glBindBuffer(GL_ARRAY_BUFFER,0);
glDeleteBuffers(1, &this->_id);
}
glGenBuffers(1,&this->_id);
glBindBuffer(GL_ARRAY_BUFFER, this->_id);
glBufferData(GL_ARRAY_BUFFER, this->max_size()*sizeof(float), vertices.size() == 0 ? NULL : vertices.data(), this->_mode);
uint32_t layer = 0,accumulateWeight = 0,totalWeight = static_cast<uint32_t>(this->weight());
for(uint8_t attribute : this->_layout) {
glVertexAttribPointer(layer, attribute, GL_FLOAT, GL_FALSE, totalWeight * sizeof(float), (void*)(accumulateWeight * sizeof(float)));
glEnableVertexAttribArray(layer++);
accumulateWeight += attribute;
}
}
bool VerticeBuffer::compare(const Layout & layout) const {
return this->_layout == layout;
}
bool VerticeBuffer::operator==(const VerticeBuffer & vbo) const {
return this->_id == vbo._id;
}
bool VerticeBuffer::operator!=(const VerticeBuffer & vbo) const {
return this->_id != vbo._id;
}
bool VerticeBuffer::operator>(const VerticeBuffer & vbo) const {
return this->_id > vbo._id;
}
bool VerticeBuffer::operator>=(const VerticeBuffer & vbo) const {
return this->_id >= vbo._id;
}
bool VerticeBuffer::operator<(const VerticeBuffer & vbo) const {
return this->_id < vbo._id;
}
bool VerticeBuffer::operator<=(const VerticeBuffer & vbo) const {
return this->_id <= vbo._id;
}
std::strong_ordering VerticeBuffer::operator<=>(const VerticeBuffer & vbo) const {
return this->_id <=> vbo._id;
}
VerticeBuffer & operator<<(VerticeBuffer & vbo,const std::initializer_list<float> & data) {
vbo.push_back(data);
return vbo;
}
VerticeBuffer & operator<<(VerticeBuffer & vbo,const std::vector<float> & data) {
vbo.push_back(data);
return vbo;
}
}
\ No newline at end of file
#pragma once
#include "DynamicBuffer.hpp"
#include <compare>
#include "VertexArray.hpp"
#include "Layout.hpp"
namespace megu {
class VerticeBuffer : public DynamicBuffer<float, GL_ARRAY_BUFFER> {
private:
const VertexArray * _vao;
GLuint _id;
GLuint _mode;
Layout _layout;
public:
VerticeBuffer() = delete;
VerticeBuffer(const VertexArray & vao, const Layout_Initializer &, size_t=2048, uint32_t=GL_DYNAMIC_DRAW);
VerticeBuffer(const VertexArray & vao, const std::vector<float> &, const Layout &, uint32_t=GL_DYNAMIC_DRAW);
VerticeBuffer(const VerticeBuffer &) = delete;
virtual ~VerticeBuffer();
const Layout & layout() const {return this->_layout;}
size_t weight() const;
size_t vertices() const;
virtual GLuint identifier() const;
virtual void bind() const;
virtual void unbind() const;
virtual void generate(const std::vector<float> &);
bool compare(const Layout &) const;
bool operator==(const VerticeBuffer &) const;
bool operator!=(const VerticeBuffer &) const;
bool operator<=(const VerticeBuffer &) const;
bool operator>=(const VerticeBuffer &) const;
bool operator<(const VerticeBuffer &) const;
bool operator>(const VerticeBuffer &) const;
std::strong_ordering operator<=>(const VerticeBuffer &) const;
friend VerticeBuffer & operator<<(VerticeBuffer &, const std::initializer_list<float> &);
friend VerticeBuffer & operator<<(VerticeBuffer &, const std::vector<float> &);
};
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment