Add subimage to texture
This commit is contained in:
parent
913285e57a
commit
1c4d5cd304
@ -23,13 +23,18 @@
|
|||||||
|
|
||||||
namespace egn{
|
namespace egn{
|
||||||
|
|
||||||
|
//Represent a 3D point
|
||||||
using point = math::vec3<float>;
|
using point = math::vec3<float>;
|
||||||
|
|
||||||
|
//Represent a line segment in 3D space given the end points
|
||||||
class line_segment
|
class line_segment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
point point1;
|
point point1;
|
||||||
point point2;
|
point point2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Represent a 2D rectangle in 3D space given the four corners
|
||||||
class rectangle
|
class rectangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -38,6 +43,8 @@ namespace egn{
|
|||||||
point point3;
|
point point3;
|
||||||
point point4;
|
point point4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Axis aligned bounding box. Given the 2 opposite corners.
|
||||||
class aabb
|
class aabb
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -52,6 +59,8 @@ namespace egn{
|
|||||||
aabb& operator=(const aabb&) = default;
|
aabb& operator=(const aabb&) = default;
|
||||||
aabb& operator=(aabb&&) = default;
|
aabb& operator=(aabb&&) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//3D sphere represented using a point and radius
|
||||||
class sphere
|
class sphere
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -25,6 +25,9 @@
|
|||||||
|
|
||||||
namespace egn{
|
namespace egn{
|
||||||
|
|
||||||
|
//Virtual base for camera types
|
||||||
|
//Provides general object functionality as well as projection and view matrices.
|
||||||
|
//Derived classes must provide method of recalculating the projection matrix.
|
||||||
class camera_iface : public object_base
|
class camera_iface : public object_base
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -41,16 +44,19 @@ namespace egn{
|
|||||||
GLfloat m_far = 100; //far clipping plane in camera space
|
GLfloat m_far = 100; //far clipping plane in camera space
|
||||||
|
|
||||||
public:
|
public:
|
||||||
camera_iface() = default;
|
camera_iface(void) = default;
|
||||||
|
//Initialize with given projection matrix and clipping planes
|
||||||
camera_iface(const math::mat4<GLfloat>& proj, GLfloat n, GLfloat f);
|
camera_iface(const math::mat4<GLfloat>& proj, GLfloat n, GLfloat f);
|
||||||
camera_iface(const camera_iface&) = default;
|
camera_iface(const camera_iface&) = default;
|
||||||
camera_iface(camera_iface&&) = default;
|
camera_iface(camera_iface&&) = default;
|
||||||
virtual ~camera_iface() = default;
|
virtual ~camera_iface(void) = default;
|
||||||
|
|
||||||
camera_iface& operator=(const camera_iface&) = default;
|
camera_iface& operator=(const camera_iface&) = default;
|
||||||
camera_iface& operator=(camera_iface&&) = default;
|
camera_iface& operator=(camera_iface&&) = default;
|
||||||
|
|
||||||
|
//Set the camera's location and update relevant data structures
|
||||||
void set_position(const math::vec3<GLfloat>& pos)override;
|
void set_position(const math::vec3<GLfloat>& pos)override;
|
||||||
|
//Set the camera's facing angle and update relevant data structures
|
||||||
void set_orientation(const math::quaternion<GLfloat>& distance)override;
|
void set_orientation(const math::quaternion<GLfloat>& distance)override;
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
@ -62,18 +68,21 @@ namespace egn{
|
|||||||
//setters
|
//setters
|
||||||
void set_near_plane(GLfloat n);
|
void set_near_plane(GLfloat n);
|
||||||
void set_far_plane(GLfloat f);
|
void set_far_plane(GLfloat f);
|
||||||
|
//No control over matrices directly is done purposefully
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void recalc_view_matrix()const;
|
void recalc_view_matrix()const;
|
||||||
virtual void recalc_projection_matrix()const = 0;
|
virtual void recalc_projection_matrix()const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Camera which performs an orthographic projection. Essentially camera will have no depth perspective
|
||||||
class ortho_camera : public camera_iface
|
class ortho_camera : public camera_iface
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
GLfloat m_width, m_height; //width and height of the camera space box
|
GLfloat m_width, m_height; //width and height of the camera space box
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
//Build camera with width, height, near, and far planes
|
||||||
ortho_camera(GLfloat w, GLfloat h, GLfloat n, GLfloat f);
|
ortho_camera(GLfloat w, GLfloat h, GLfloat n, GLfloat f);
|
||||||
ortho_camera(const ortho_camera&) = default;
|
ortho_camera(const ortho_camera&) = default;
|
||||||
ortho_camera(ortho_camera&&) = default;
|
ortho_camera(ortho_camera&&) = default;
|
||||||
@ -82,9 +91,11 @@ namespace egn{
|
|||||||
ortho_camera& operator=(const ortho_camera&) = default;
|
ortho_camera& operator=(const ortho_camera&) = default;
|
||||||
ortho_camera& operator=(ortho_camera&&) = default;
|
ortho_camera& operator=(ortho_camera&&) = default;
|
||||||
|
|
||||||
|
//Getters
|
||||||
GLfloat get_projection_width()const;
|
GLfloat get_projection_width()const;
|
||||||
GLfloat get_projection_height()const;
|
GLfloat get_projection_height()const;
|
||||||
|
|
||||||
|
//Setters
|
||||||
void set_projection_width(GLfloat w);
|
void set_projection_width(GLfloat w);
|
||||||
void set_projection_height(GLfloat h);
|
void set_projection_height(GLfloat h);
|
||||||
void set_projection_box(GLfloat w, GLfloat h);
|
void set_projection_box(GLfloat w, GLfloat h);
|
||||||
|
|||||||
@ -23,17 +23,21 @@
|
|||||||
|
|
||||||
namespace egn{
|
namespace egn{
|
||||||
|
|
||||||
|
//How far away before a collision is considered to have occurred
|
||||||
static constexpr float default_collision_epsilon = 1.0e-10f;
|
static constexpr float default_collision_epsilon = 1.0e-10f;
|
||||||
|
|
||||||
class collidable_visitor;
|
class collidable_visitor;
|
||||||
|
|
||||||
|
//Anything which derives from this is considered collidable and must be comparible to any other collidable
|
||||||
class collidable_iface
|
class collidable_iface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//Check if this and the other collidable have collided
|
||||||
virtual bool check_collision(const collidable_iface& c, float epsilon)const = 0;
|
virtual bool check_collision(const collidable_iface& c, float epsilon)const = 0;
|
||||||
virtual void accept_visitor(collidable_visitor& v)const = 0;
|
virtual void accept_visitor(collidable_visitor& v)const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//CRTP collidable to allow the collision checks to determine the concrete type of the collidable
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
class collidable : public collidable_iface
|
class collidable : public collidable_iface
|
||||||
{
|
{
|
||||||
@ -46,14 +50,23 @@ namespace egn{
|
|||||||
|
|
||||||
namespace collision{
|
namespace collision{
|
||||||
|
|
||||||
|
//Basic collidable objects
|
||||||
|
|
||||||
|
//A 1D point
|
||||||
class point : public egn::point, public collidable<point>
|
class point : public egn::point, public collidable<point>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using egn::point::point;
|
using egn::point::point;
|
||||||
using egn::point::operator=;
|
using egn::point::operator=;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//A 2D line
|
||||||
class line_segment : public egn::line_segment, public collidable<line_segment>{};
|
class line_segment : public egn::line_segment, public collidable<line_segment>{};
|
||||||
|
|
||||||
|
//A 2D rectangle
|
||||||
class rectangle : public egn::rectangle, public collidable<rectangle>{};
|
class rectangle : public egn::rectangle, public collidable<rectangle>{};
|
||||||
|
|
||||||
|
//A 3D bounding box
|
||||||
class aabb : public egn::aabb, public collidable<aabb>
|
class aabb : public egn::aabb, public collidable<aabb>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -62,6 +75,8 @@ namespace egn{
|
|||||||
aabb(const egn::aabb& b);
|
aabb(const egn::aabb& b);
|
||||||
aabb& operator=(const egn::aabb& b);
|
aabb& operator=(const egn::aabb& b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//A 3D sphere
|
||||||
class sphere : public egn::sphere, public collidable<sphere>
|
class sphere : public egn::sphere, public collidable<sphere>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -73,6 +88,7 @@ namespace egn{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//base class for collision visitor to provide polymorphic access to visitation functions
|
||||||
class collidable_visitor
|
class collidable_visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -83,6 +99,7 @@ namespace egn{
|
|||||||
virtual void visit(const collision::point& p) = 0;
|
virtual void visit(const collision::point& p) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Templated visitor to allow checking collision from polymorphic types
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class collision_visitor : public collidable_visitor
|
class collision_visitor : public collidable_visitor
|
||||||
{
|
{
|
||||||
@ -100,6 +117,7 @@ namespace egn{
|
|||||||
constexpr bool result()const;
|
constexpr bool result()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Concrete collision detection that is eventually called
|
||||||
//bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon = default_collision_epsilon);
|
//bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon = default_collision_epsilon);
|
||||||
bool check_collision(const aabb& l, const aabb& r, float epsilon = default_collision_epsilon);
|
bool check_collision(const aabb& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||||
bool check_collision(const aabb& l, const sphere& r, float epsilon = default_collision_epsilon);
|
bool check_collision(const aabb& l, const sphere& r, float epsilon = default_collision_epsilon);
|
||||||
@ -128,21 +146,23 @@ namespace egn{
|
|||||||
bool check_collision(const point& l, const rectangle& r, float epsilon = default_collision_epsilon);
|
bool check_collision(const point& l, const rectangle& r, float epsilon = default_collision_epsilon);
|
||||||
|
|
||||||
|
|
||||||
|
//Check collision between this and c via a visitor
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool collidable<Derived>::check_collision(const collidable_iface& c, float epsilon)const{
|
bool collidable<Derived>::check_collision(const collidable_iface& c, float epsilon)const{
|
||||||
collision_visitor<Derived> vis(static_cast<const Derived&>(*this), epsilon);
|
collision_visitor<Derived> vis(static_cast<const Derived&>(*this), epsilon); //Determine our true type for visitor
|
||||||
c.accept_visitor(vis);
|
c.accept_visitor(vis); //have c give its true type to our visitor and check for collision
|
||||||
return vis.result();
|
return vis.result();
|
||||||
}
|
}
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void collidable<Derived>::accept_visitor(collidable_visitor& v)const{
|
void collidable<Derived>::accept_visitor(collidable_visitor& v)const{
|
||||||
v.visit(static_cast<const Derived&>(*this));
|
v.visit(static_cast<const Derived&>(*this)); //Give the visitor our true type to allow calling correct collision check function
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr collision_visitor<T>::collision_visitor(const T& l, float epsilon):
|
constexpr collision_visitor<T>::collision_visitor(const T& l, float epsilon):
|
||||||
m_l(l),
|
m_l(l),
|
||||||
m_epsilon(epsilon){}
|
m_epsilon(epsilon){}
|
||||||
|
//Call correct concrete function for given collision
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void collision_visitor<T>::visit(const collision::aabb& a){
|
void collision_visitor<T>::visit(const collision::aabb& a){
|
||||||
m_result = check_collision(m_l, a, m_epsilon);
|
m_result = check_collision(m_l, a, m_epsilon);
|
||||||
|
|||||||
77
include/engine/font.hpp
Normal file
77
include/engine/font.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OUR_DICK_ENGINE_FONT_HPP
|
||||||
|
#define OUR_DICK_ENGINE_FONT_HPP
|
||||||
|
|
||||||
|
#include <freetype2/ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "graphics/texture.hpp"
|
||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
|
namespace egn{
|
||||||
|
|
||||||
|
class font
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//ascii texture atlas
|
||||||
|
const char* m_bitmap_handle;
|
||||||
|
//When rendering unicode, load up new textures per code page to create many atlases
|
||||||
|
std::map<int, const char*> m_extra_codepages;
|
||||||
|
//stb or freetype font handle
|
||||||
|
|
||||||
|
public:
|
||||||
|
//load the font file and process it with stb/freetype lib
|
||||||
|
//render out basic ascii characters to bitmap texture atlas
|
||||||
|
//maybe do signed distance fonts? example: https://github.com/ShoYamanishi/SDFont
|
||||||
|
//dynamically add new codepage textures for rendering non-ascii
|
||||||
|
};
|
||||||
|
|
||||||
|
class font_generator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static inline bool s_initialized = false;
|
||||||
|
static inline FT_Library s_ft;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FT_Face m_face = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
font_generator(const char* file);
|
||||||
|
~font_generator(void);
|
||||||
|
|
||||||
|
//params:
|
||||||
|
// start_codepoint: unicode character at which the atlas starts
|
||||||
|
// count: number of characters to make in the atlas
|
||||||
|
// glyph_width: requested pixel width of glyph
|
||||||
|
// glyph_height: requested pixel height of glyph
|
||||||
|
// atlas_width: requested pixel width of atlas
|
||||||
|
// atlas_height: requested pixel height of atlas
|
||||||
|
std::optional<gfx::texture> generate_atlas(int start_codepoint, int count, int glyph_width, int glyph_height, int atlas_width, int atlas_height);
|
||||||
|
std::optional<gfx::texture> generate_glyph(char character, int width, int height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool initialize_freetype_(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
This file is a part of our_dick
|
This file is a part of our_dick
|
||||||
Copyright (C) 2020 rexy712
|
Copyright (C) 2020-2022 rexy712
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published by
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -29,6 +29,9 @@ namespace gfx{
|
|||||||
public:
|
public:
|
||||||
using texture::texture;
|
using texture::texture;
|
||||||
using texture::operator=;
|
using texture::operator=;
|
||||||
|
|
||||||
|
//tmp
|
||||||
|
material(texture&&);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,16 +36,16 @@ namespace gfx{
|
|||||||
weak_texture_handle(const texture& tex);
|
weak_texture_handle(const texture& tex);
|
||||||
weak_texture_handle(const weak_texture_handle&) = default;
|
weak_texture_handle(const weak_texture_handle&) = default;
|
||||||
weak_texture_handle(weak_texture_handle&&) = default;
|
weak_texture_handle(weak_texture_handle&&) = default;
|
||||||
~weak_texture_handle() = default;
|
~weak_texture_handle(void) = default;
|
||||||
|
|
||||||
weak_texture_handle& operator=(const weak_texture_handle&) = default;
|
weak_texture_handle& operator=(const weak_texture_handle&) = default;
|
||||||
weak_texture_handle& operator=(weak_texture_handle&&) = default;
|
weak_texture_handle& operator=(weak_texture_handle&&) = default;
|
||||||
|
|
||||||
GLuint raw()const;
|
GLuint raw(void)const;
|
||||||
GLsizei get_width()const;
|
GLsizei get_width(void)const;
|
||||||
GLsizei get_height()const;
|
GLsizei get_height(void)const;
|
||||||
|
|
||||||
void bind()const;
|
void bind(void)const;
|
||||||
void bind_unit(GLuint tunit)const;
|
void bind_unit(GLuint tunit)const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,29 +81,35 @@ namespace gfx{
|
|||||||
GLsizei m_height = 0;
|
GLsizei m_height = 0;
|
||||||
GLenum m_format = 0;
|
GLenum m_format = 0;
|
||||||
GLenum m_type = GL_UNSIGNED_BYTE;
|
GLenum m_type = GL_UNSIGNED_BYTE;
|
||||||
|
bool m_mipmapped = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//create the texture with no image data
|
//create the texture with no image data
|
||||||
texture();
|
texture(void);
|
||||||
texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
|
texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
|
||||||
texture(GLenum format, GLsizei w, GLsizei h, GLenum type);
|
texture(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
|
||||||
//create the texture with image data from 'i'
|
//create the texture with image data from 'i'
|
||||||
texture(const egn::image& i);
|
texture(const egn::image& i, bool mipmap = true);
|
||||||
texture(const egn::deferred_image& i);
|
texture(const egn::deferred_image& i, bool mipmap = true);
|
||||||
texture(const texture&) = delete;
|
texture(const texture&);
|
||||||
texture(texture&&);
|
texture(texture&&);
|
||||||
~texture();
|
~texture(void);
|
||||||
|
|
||||||
texture& operator=(const texture&) = delete;
|
texture& operator=(const texture&);
|
||||||
texture& operator=(texture&&);
|
texture& operator=(texture&&);
|
||||||
|
|
||||||
GLuint raw()const;
|
GLuint raw(void)const;
|
||||||
|
|
||||||
//overwrite the current image data with 'i'
|
//overwrite the current image data with 'i'
|
||||||
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
|
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
|
||||||
bool set_image(const egn::image& i);
|
bool set_image(const egn::image& i);
|
||||||
bool set_image(const egn::deferred_image& i);
|
bool set_image(const egn::deferred_image& i);
|
||||||
|
|
||||||
|
bool set_subimage(const unsigned char* data, GLenum format, GLenum type,
|
||||||
|
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h);
|
||||||
|
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset);
|
||||||
|
bool set_subimage(const egn::deferred_image& i, GLsizei xoffset, GLsizei yoffset);
|
||||||
|
|
||||||
//change wrap mode for both x and y
|
//change wrap mode for both x and y
|
||||||
void set_wrap_mode(wrap w);
|
void set_wrap_mode(wrap w);
|
||||||
void set_wrap_mode(wrap w, wrap h);
|
void set_wrap_mode(wrap w, wrap h);
|
||||||
@ -116,25 +122,31 @@ namespace gfx{
|
|||||||
void set_mag_filter(magfilter m);
|
void set_mag_filter(magfilter m);
|
||||||
void set_min_filter(minfilter m);
|
void set_min_filter(minfilter m);
|
||||||
|
|
||||||
magfilter get_mag_filter()const;
|
magfilter get_mag_filter(void)const;
|
||||||
minfilter get_min_filter()const;
|
minfilter get_min_filter(void)const;
|
||||||
math::vec4<GLfloat> get_border_color()const;
|
math::vec4<GLfloat> get_border_color(void)const;
|
||||||
|
|
||||||
wrap get_wrap_x()const;
|
wrap get_wrap_x(void)const;
|
||||||
wrap get_wrap_y()const;
|
wrap get_wrap_y(void)const;
|
||||||
|
|
||||||
GLsizei get_width()const;
|
GLsizei get_width(void)const;
|
||||||
GLsizei get_height()const;
|
GLsizei get_height(void)const;
|
||||||
|
|
||||||
|
void enable_auto_mipmap(bool enable);
|
||||||
|
void generate_mipmap(void);
|
||||||
|
|
||||||
//release ownership of this texture object
|
//release ownership of this texture object
|
||||||
GLuint release();
|
GLuint release(void);
|
||||||
|
|
||||||
//bind to GL_TEXTURE_2D
|
//bind to GL_TEXTURE_2D
|
||||||
void bind()const;
|
void bind(void)const;
|
||||||
//bind to given texture unit and load into given program uniform location
|
//bind to given texture unit and load into given program uniform location
|
||||||
void bind_unit(GLuint tunit)const;
|
void bind_unit(GLuint tunit)const;
|
||||||
|
|
||||||
weak_texture_handle create_handle()const;
|
weak_texture_handle create_handle(void)const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool create_texture_storage_(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ private:
|
|||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
basic_framebuffer m_fb;
|
basic_framebuffer m_fb;
|
||||||
|
gfx::fbo m_primary_fb;
|
||||||
gfx::shader_program* m_sprite_shader;
|
gfx::shader_program* m_sprite_shader;
|
||||||
gfx::shader_program* m_screen_shader;
|
gfx::shader_program* m_screen_shader;
|
||||||
gfx::vbo m_vbo;
|
gfx::vbo m_vbo;
|
||||||
|
|||||||
4
makefile
4
makefile
@ -26,7 +26,7 @@ DEPDIR::=$(OBJDIR)/dep
|
|||||||
LIBDIRS::=lib
|
LIBDIRS::=lib
|
||||||
INCLUDE_DIRS::=include
|
INCLUDE_DIRS::=include
|
||||||
CFLAGS::=-std=c18 -Wall -pedantic -Wextra
|
CFLAGS::=-std=c18 -Wall -pedantic -Wextra
|
||||||
CXXFLAGS::=-std=c++20 -Wall -pedantic -Wextra -fno-rtti -fno-exceptions
|
CXXFLAGS::=-std=c++20 -Wall -pedantic -Wextra -fno-rtti -fno-exceptions $(shell pkg-config --cflags freetype2)
|
||||||
DEBUG_CFLAGS::=
|
DEBUG_CFLAGS::=
|
||||||
DEBUG_CXXFLAGS::=-DOUR_DICK_DEBUG=2
|
DEBUG_CXXFLAGS::=-DOUR_DICK_DEBUG=2
|
||||||
EXT::=cpp
|
EXT::=cpp
|
||||||
@ -41,7 +41,7 @@ ifneq ($(WINDOWS),1)
|
|||||||
#*nix settings
|
#*nix settings
|
||||||
CC::=gcc
|
CC::=gcc
|
||||||
CXX::=g++
|
CXX::=g++
|
||||||
LDLIBS::=-lglfw -lglad -ldl -lm -lportaudio -lsndfile -lpthread -lrexy
|
LDLIBS::=-lglfw -lglad -ldl -lm -lportaudio -lsndfile -lpthread -lrexy $(shell pkg-config --libs freetype2)
|
||||||
ifeq ($(shell uname -s),Linux)
|
ifeq ($(shell uname -s),Linux)
|
||||||
LDLIBS+=-lasound
|
LDLIBS+=-lasound
|
||||||
endif
|
endif
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
#include "math/mat.hpp"
|
#include "math/mat.hpp"
|
||||||
|
|
||||||
#include "graphics/gl_include.hpp" //GLfloat
|
#include "graphics/gl_include.hpp" //GLfloat
|
||||||
|
#include "engine/font.hpp"
|
||||||
|
|
||||||
gfx::unified_mesh square_mesh(const gfx::material& blank, const gfx::material& o, const gfx::material& x){
|
gfx::unified_mesh square_mesh(const gfx::material& blank, const gfx::material& o, const gfx::material& x){
|
||||||
static constexpr gfx::vertex s_vertices[] = {
|
static constexpr gfx::vertex s_vertices[] = {
|
||||||
@ -64,7 +64,6 @@ board::board(egn::resource_manager& resman):
|
|||||||
blank = resman.emplace_material("assets/images/blank.jpg", egn::deferred_image("assets/images/blank.jpg", true)).first;
|
blank = resman.emplace_material("assets/images/blank.jpg", egn::deferred_image("assets/images/blank.jpg", true)).first;
|
||||||
o = resman.emplace_material("assets/images/o.jpg", egn::deferred_image("assets/images/o.jpg", true)).first;
|
o = resman.emplace_material("assets/images/o.jpg", egn::deferred_image("assets/images/o.jpg", true)).first;
|
||||||
x = resman.emplace_material("assets/images/x.jpg", egn::deferred_image("assets/images/x.jpg", true)).first;
|
x = resman.emplace_material("assets/images/x.jpg", egn::deferred_image("assets/images/x.jpg", true)).first;
|
||||||
x = resman.emplace_material("assets/images/x.jpg", egn::deferred_image("assets/images/x.jpg", true)).first;
|
|
||||||
|
|
||||||
if(!resman.has_model("square")){
|
if(!resman.has_model("square")){
|
||||||
sq = resman.emplace_model("square", square_mesh(*blank, *o, *x)).first;
|
sq = resman.emplace_model("square", square_mesh(*blank, *o, *x)).first;
|
||||||
|
|||||||
55
src/engine/font.cpp
Normal file
55
src/engine/font.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "engine/font.hpp"
|
||||||
|
|
||||||
|
namespace egn{
|
||||||
|
|
||||||
|
font_generator::font_generator(const char* file){
|
||||||
|
initialize_freetype_();
|
||||||
|
if(FT_New_Face(s_ft, file, 0, &m_face)){
|
||||||
|
debug_print_error("Failed to initialize font '%s'\n", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font_generator::~font_generator(void){
|
||||||
|
FT_Done_Face(m_face);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<gfx::texture> font_generator::generate_glyph(char character, int width, int height){
|
||||||
|
FT_Set_Pixel_Sizes(m_face, width, height);
|
||||||
|
if(FT_Load_Char(m_face, character, FT_LOAD_RENDER)){
|
||||||
|
debug_print_error("Failed to load character '%c', from font '%s'\n", character, m_face->family_name);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto& bitmap = m_face->glyph->bitmap;
|
||||||
|
return {gfx::texture(bitmap.buffer, GL_RED, bitmap.width, bitmap.rows, GL_UNSIGNED_BYTE)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool font_generator::initialize_freetype_(void){
|
||||||
|
if(!s_initialized){
|
||||||
|
if(FT_Init_FreeType(&s_ft)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (s_initialized = true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/graphics/material.cpp
Normal file
28
src/graphics/material.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of our_dick
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "graphics/material.hpp"
|
||||||
|
|
||||||
|
#include <utility> //move
|
||||||
|
|
||||||
|
namespace gfx{
|
||||||
|
|
||||||
|
material::material(texture&& t):
|
||||||
|
texture(std::move(t)){}
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
|
||||||
#include <utility> //exchange, swap
|
#include <utility> //exchange, swap
|
||||||
|
#include <rexy/utility.hpp>
|
||||||
|
|
||||||
namespace gfx{
|
namespace gfx{
|
||||||
|
|
||||||
@ -65,62 +66,88 @@ namespace gfx{
|
|||||||
};
|
};
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
[[maybe_unused]]
|
||||||
|
static GLint save_unpack_alignment_(void){
|
||||||
|
int old_alignment;
|
||||||
|
glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_alignment);
|
||||||
|
return old_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture::texture(void){
|
||||||
|
|
||||||
texture::texture(){
|
|
||||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_tex_id);
|
glCreateTextures(GL_TEXTURE_2D, 1, &m_tex_id);
|
||||||
}
|
}
|
||||||
texture::texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type):
|
texture::texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap):
|
||||||
m_width(w), m_height(h),
|
m_width(w), m_height(h),
|
||||||
m_format(format), m_type(type)
|
m_format(format), m_type(type),
|
||||||
|
m_mipmapped(mipmap)
|
||||||
{
|
{
|
||||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_tex_id);
|
glCreateTextures(GL_TEXTURE_2D, 1, &m_tex_id);
|
||||||
switch(m_format){
|
GLint old_alignment = save_unpack_alignment_();
|
||||||
case GL_RED:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_R8, m_width, m_height);
|
if(!create_texture_storage_()){
|
||||||
break;
|
debug_print_error("Failed to create texture storage\n");
|
||||||
case GL_RG:
|
return;
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RG8, m_width, m_height);
|
}
|
||||||
break;
|
|
||||||
case GL_RGB:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RGB8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
case GL_RGBA:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RGBA8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_print_error("Unsupported format passed to texture constructor\n");
|
|
||||||
glDeleteTextures(1, &m_tex_id);
|
|
||||||
m_tex_id = 0;
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
glTextureSubImage2D(m_tex_id, 0, 0, 0, m_width, m_height, m_format, m_type, data);
|
glTextureSubImage2D(m_tex_id, 0, 0, 0, m_width, m_height, m_format, m_type, data);
|
||||||
glGenerateTextureMipmap(m_tex_id);
|
if(m_mipmapped)
|
||||||
|
generate_mipmap();
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||||
}
|
}
|
||||||
texture::texture(GLenum format, GLsizei w, GLsizei h, GLenum type):
|
texture::texture(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap):
|
||||||
texture(nullptr, format, w, h, type){}
|
texture(nullptr, format, w, h, type, mipmap){}
|
||||||
texture::texture(const egn::image& i):
|
texture::texture(const egn::image& i, bool mipmap):
|
||||||
texture()
|
texture()
|
||||||
{
|
{
|
||||||
|
m_mipmapped = mipmap;
|
||||||
set_image(i);
|
set_image(i);
|
||||||
}
|
}
|
||||||
texture::texture(const egn::deferred_image& i):
|
texture::texture(const egn::deferred_image& i, bool mipmap):
|
||||||
texture()
|
texture()
|
||||||
{
|
{
|
||||||
|
m_mipmapped = mipmap;
|
||||||
set_image(i);
|
set_image(i);
|
||||||
}
|
}
|
||||||
|
texture::texture(const texture& t):
|
||||||
|
m_width(t.m_width), m_height(t.m_height),
|
||||||
|
m_format(t.m_format), m_type(t.m_type),
|
||||||
|
m_mipmapped(t.m_mipmapped)
|
||||||
|
{
|
||||||
|
//Copying textures is not preferable so generate a debug warning
|
||||||
|
debug_print_warn("Copy constructing texture!\n");
|
||||||
|
|
||||||
|
glCreateTextures(GL_TEXTURE_2D, 1, &m_tex_id);
|
||||||
|
GLint old_alignment = save_unpack_alignment_();
|
||||||
|
|
||||||
|
if(!create_texture_storage_()){
|
||||||
|
debug_print_error("Failed to create texture storage\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glCopyImageSubData(t.m_tex_id, GL_TEXTURE_2D, 0, 0, 0, 0,
|
||||||
|
m_tex_id, GL_TEXTURE_2D, 0, 0, 0, 0,
|
||||||
|
m_width, m_height, 1);
|
||||||
|
if(m_mipmapped)
|
||||||
|
generate_mipmap();
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||||
|
}
|
||||||
texture::texture(texture&& t):
|
texture::texture(texture&& t):
|
||||||
m_tex_id(std::exchange(t.m_tex_id, 0)){}
|
m_tex_id(std::exchange(t.m_tex_id, 0)),
|
||||||
texture::~texture(){
|
m_width(t.m_width), m_height(t.m_height),
|
||||||
|
m_format(t.m_format), m_type(t.m_type){}
|
||||||
|
texture::~texture(void){
|
||||||
glDeleteTextures(1, &m_tex_id);
|
glDeleteTextures(1, &m_tex_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texture& texture::operator=(const texture& t){
|
||||||
|
debug_print_warn("Copy assigning texture!\n");
|
||||||
|
return (*this = texture(t));
|
||||||
|
}
|
||||||
texture& texture::operator=(texture&& t){
|
texture& texture::operator=(texture&& t){
|
||||||
std::swap(m_tex_id, t.m_tex_id);
|
std::swap(m_tex_id, t.m_tex_id);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
GLuint texture::raw()const{
|
GLuint texture::raw(void)const{
|
||||||
return m_tex_id;
|
return m_tex_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +156,8 @@ namespace gfx{
|
|||||||
debug_print_error("Image is invalid\n");
|
debug_print_error("Image is invalid\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
GLint old_alignment = save_unpack_alignment_();
|
||||||
|
|
||||||
if(m_width != w || m_height != h || m_format != format){
|
if(m_width != w || m_height != h || m_format != format){
|
||||||
if(m_format != 0){
|
if(m_format != 0){
|
||||||
debug_print_warn("Regenerating texture\n");
|
debug_print_warn("Regenerating texture\n");
|
||||||
@ -137,27 +166,17 @@ namespace gfx{
|
|||||||
}
|
}
|
||||||
m_width = w;
|
m_width = w;
|
||||||
m_height = h;
|
m_height = h;
|
||||||
switch(format){
|
|
||||||
case GL_RED:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_R8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
case GL_RG:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RG8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
case GL_RGB:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RGB8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
case GL_RGBA:
|
|
||||||
glTextureStorage2D(m_tex_id, 1, GL_RGBA8, m_width, m_height);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug_print_error("Invalid format for texture\n");
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
m_format = format;
|
m_format = format;
|
||||||
|
if(!create_texture_storage_()){
|
||||||
|
debug_print_error("Invalid format for texture\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glTextureSubImage2D(m_tex_id, 0, 0, 0, m_width, m_height, m_format, type, data);
|
glTextureSubImage2D(m_tex_id, 0, 0, 0, m_width, m_height, m_format, type, data);
|
||||||
glGenerateTextureMipmap(m_tex_id);
|
if(m_mipmapped)
|
||||||
|
generate_mipmap();
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool texture::set_image(const egn::image& i){
|
bool texture::set_image(const egn::image& i){
|
||||||
@ -167,6 +186,37 @@ namespace gfx{
|
|||||||
return set_image(i.get_image());
|
return set_image(i.get_image());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool texture::set_subimage(const unsigned char* data, GLenum format, GLenum type,
|
||||||
|
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h)
|
||||||
|
{
|
||||||
|
if(!data){
|
||||||
|
debug_print_error("Image is invalid\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(yoffset >= m_height || xoffset >= m_width){
|
||||||
|
debug_print_error("Texture is smaller than requested offsets: (%d, %d)\n", xoffset, yoffset);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint old_alignment = save_unpack_alignment_();
|
||||||
|
|
||||||
|
h = rexy::min(h, m_height - yoffset);
|
||||||
|
w = rexy::min(w, m_width - xoffset);
|
||||||
|
|
||||||
|
glTextureSubImage2D(m_tex_id, 0, xoffset, yoffset, w, h, format, type, data);
|
||||||
|
generate_mipmap();
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool texture::set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset){
|
||||||
|
return set_subimage(i.data(), convert_channel_to_format(i.get_channels()), GL_UNSIGNED_BYTE, xoffset, yoffset, i.get_width(), i.get_height());
|
||||||
|
}
|
||||||
|
bool texture::set_subimage(const egn::deferred_image& i, GLsizei xoffset, GLsizei yoffset){
|
||||||
|
return set_subimage(i.get_image(), xoffset, yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void texture::set_wrap_mode(wrap w){
|
void texture::set_wrap_mode(wrap w){
|
||||||
glTextureParameteri(m_tex_id, GL_TEXTURE_WRAP_S, static_cast<GLint>(w));
|
glTextureParameteri(m_tex_id, GL_TEXTURE_WRAP_S, static_cast<GLint>(w));
|
||||||
glTextureParameteri(m_tex_id, GL_TEXTURE_WRAP_T, static_cast<GLint>(w));
|
glTextureParameteri(m_tex_id, GL_TEXTURE_WRAP_T, static_cast<GLint>(w));
|
||||||
@ -196,67 +246,99 @@ namespace gfx{
|
|||||||
void texture::set_min_filter(minfilter m){
|
void texture::set_min_filter(minfilter m){
|
||||||
glTextureParameteri(m_tex_id, GL_TEXTURE_MIN_FILTER, static_cast<GLint>(m));
|
glTextureParameteri(m_tex_id, GL_TEXTURE_MIN_FILTER, static_cast<GLint>(m));
|
||||||
}
|
}
|
||||||
auto texture::get_mag_filter()const -> magfilter{
|
auto texture::get_mag_filter(void)const -> magfilter{
|
||||||
GLint filter;
|
GLint filter;
|
||||||
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_MAG_FILTER, &filter);
|
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_MAG_FILTER, &filter);
|
||||||
return static_cast<magfilter>(filter);
|
return static_cast<magfilter>(filter);
|
||||||
}
|
}
|
||||||
auto texture::get_min_filter()const -> minfilter{
|
auto texture::get_min_filter(void)const -> minfilter{
|
||||||
GLint filter;
|
GLint filter;
|
||||||
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_MIN_FILTER, &filter);
|
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_MIN_FILTER, &filter);
|
||||||
return static_cast<minfilter>(filter);
|
return static_cast<minfilter>(filter);
|
||||||
}
|
}
|
||||||
math::vec4<GLfloat> texture::get_border_color()const{
|
math::vec4<GLfloat> texture::get_border_color(void)const{
|
||||||
math::vec4<GLfloat> color;
|
math::vec4<GLfloat> color;
|
||||||
glGetTextureParameterfv(m_tex_id, GL_TEXTURE_BORDER_COLOR, color);
|
glGetTextureParameterfv(m_tex_id, GL_TEXTURE_BORDER_COLOR, color);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
auto texture::get_wrap_x()const -> wrap{
|
auto texture::get_wrap_x(void)const -> wrap{
|
||||||
GLint w;
|
GLint w;
|
||||||
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_WRAP_S, &w);
|
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_WRAP_S, &w);
|
||||||
return static_cast<wrap>(w);
|
return static_cast<wrap>(w);
|
||||||
}
|
}
|
||||||
auto texture::get_wrap_y()const -> wrap{
|
auto texture::get_wrap_y(void)const -> wrap{
|
||||||
GLint w;
|
GLint w;
|
||||||
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_WRAP_T, &w);
|
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_WRAP_T, &w);
|
||||||
return static_cast<wrap>(w);
|
return static_cast<wrap>(w);
|
||||||
}
|
}
|
||||||
GLsizei texture::get_width()const{
|
GLsizei texture::get_width(void)const{
|
||||||
return m_width;
|
return m_width;
|
||||||
}
|
}
|
||||||
GLsizei texture::get_height()const{
|
GLsizei texture::get_height(void)const{
|
||||||
return m_height;
|
return m_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint texture::release(){
|
void texture::enable_auto_mipmap(bool enable){
|
||||||
|
m_mipmapped = enable;
|
||||||
|
}
|
||||||
|
void texture::generate_mipmap(void){
|
||||||
|
glGenerateTextureMipmap(m_tex_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint texture::release(void){
|
||||||
return std::exchange(m_tex_id, 0);
|
return std::exchange(m_tex_id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void texture::bind()const{
|
void texture::bind(void)const{
|
||||||
glBindTexture(GL_TEXTURE_2D, m_tex_id);
|
glBindTexture(GL_TEXTURE_2D, m_tex_id);
|
||||||
}
|
}
|
||||||
void texture::bind_unit(GLuint tunit)const{
|
void texture::bind_unit(GLuint tunit)const{
|
||||||
glBindTextureUnit(tunit, m_tex_id);
|
glBindTextureUnit(tunit, m_tex_id);
|
||||||
}
|
}
|
||||||
weak_texture_handle texture::create_handle()const{
|
weak_texture_handle texture::create_handle(void)const{
|
||||||
return weak_texture_handle(*this);
|
return weak_texture_handle(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool texture::create_texture_storage_(void){
|
||||||
|
switch(m_format){
|
||||||
|
case GL_RED:
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTextureStorage2D(m_tex_id, 1, GL_R8, m_width, m_height);
|
||||||
|
break;
|
||||||
|
case GL_RG:
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||||
|
glTextureStorage2D(m_tex_id, 1, GL_RG8, m_width, m_height);
|
||||||
|
break;
|
||||||
|
case GL_RGB:
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTextureStorage2D(m_tex_id, 1, GL_RGB8, m_width, m_height);
|
||||||
|
break;
|
||||||
|
case GL_RGBA:
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
glTextureStorage2D(m_tex_id, 1, GL_RGBA8, m_width, m_height);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
glDeleteTextures(1, &m_tex_id);
|
||||||
|
m_tex_id = 0;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
weak_texture_handle::weak_texture_handle(const texture& tex):
|
weak_texture_handle::weak_texture_handle(const texture& tex):
|
||||||
m_texture(&tex){}
|
m_texture(&tex){}
|
||||||
|
|
||||||
GLuint weak_texture_handle::raw()const{
|
GLuint weak_texture_handle::raw(void)const{
|
||||||
return m_texture->raw();
|
return m_texture->raw();
|
||||||
}
|
}
|
||||||
GLsizei weak_texture_handle::get_width()const{
|
GLsizei weak_texture_handle::get_width(void)const{
|
||||||
return m_texture->get_width();
|
return m_texture->get_width();
|
||||||
}
|
}
|
||||||
GLsizei weak_texture_handle::get_height()const{
|
GLsizei weak_texture_handle::get_height(void)const{
|
||||||
return m_texture->get_height();
|
return m_texture->get_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
void weak_texture_handle::bind()const{
|
void weak_texture_handle::bind(void)const{
|
||||||
m_texture->bind();
|
m_texture->bind();
|
||||||
}
|
}
|
||||||
void weak_texture_handle::bind_unit(GLuint tunit)const{
|
void weak_texture_handle::bind_unit(GLuint tunit)const{
|
||||||
|
|||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "tic_tac_toe.hpp"
|
#include "tic_tac_toe.hpp"
|
||||||
|
#include "engine/font.hpp"
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
main_renderer::main_renderer(egn::resource_manager& res, int width, int height):
|
main_renderer::main_renderer(egn::resource_manager& res, int width, int height):
|
||||||
m_fb(MAX_WIDTH, MAX_HEIGHT),
|
m_fb(MAX_WIDTH, MAX_HEIGHT),
|
||||||
|
m_primary_fb(util::no_initialize),
|
||||||
m_vbo(s_vertices, sizeof(s_vertices), gfx::vbo::usage::DYNAMIC_DRAW)
|
m_vbo(s_vertices, sizeof(s_vertices), gfx::vbo::usage::DYNAMIC_DRAW)
|
||||||
{
|
{
|
||||||
if(res.has_shader("sprite_shader"))
|
if(res.has_shader("sprite_shader"))
|
||||||
@ -61,7 +62,6 @@ void main_renderer::set_vp_matrix(const math::mat4<GLfloat>& vp){
|
|||||||
m_sprite_shader->set_uniform("vp_mat", vp);
|
m_sprite_shader->set_uniform("vp_mat", vp);
|
||||||
}
|
}
|
||||||
void main_renderer::render(scene& s){
|
void main_renderer::render(scene& s){
|
||||||
const auto& vp = m_fb.get_viewport();
|
|
||||||
m_fb.bind();
|
m_fb.bind();
|
||||||
m_fb.clear_color_buffer();
|
m_fb.clear_color_buffer();
|
||||||
m_fb.clear_depth_buffer();
|
m_fb.clear_depth_buffer();
|
||||||
@ -73,10 +73,9 @@ void main_renderer::render(scene& s){
|
|||||||
(*it)->render(*m_sprite_shader);
|
(*it)->render(*m_sprite_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
m_primary_fb.bind();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
m_primary_fb.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glViewport(0, 0, vp.z(), vp.w());
|
|
||||||
|
|
||||||
m_screen_shader->use();
|
m_screen_shader->use();
|
||||||
m_screen_shader->set_uniform("texture1", m_fb.colorbuffer(), 0);
|
m_screen_shader->set_uniform("texture1", m_fb.colorbuffer(), 0);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user