1 #pragma once 2 3 #include <solarus/graphics/Renderer.h> 4 #include <solarus/graphics/glrenderer/GlShader.h> 5 #include <solarus/graphics/VertexArray.h> 6 7 namespace Solarus { 8 9 class GlShader; 10 class GlTexture; 11 12 /** 13 * @brief Opengl Renderer 14 * 15 * This renderer implements batch rendering. This minimize the state changes in 16 * the opengl driver. Sprites are accumulated in a buffer before being rendered 17 * all at once. 18 */ 19 class GlRenderer : public Renderer { 20 friend class GlTexture; 21 friend class GlShader; 22 23 public: 24 typedef void (APIENTRY *DEBUGPROC)(GLenum source, 25 GLenum type, 26 GLuint id, 27 GLenum severity, 28 GLsizei length, 29 const GLchar *message, 30 const void *userParam); 31 32 /** 33 * @brief Draw destination 34 */ 35 struct Fbo{ 36 GLuint id; 37 glm::mat4 view; 38 }; 39 40 GlRenderer(SDL_GLContext ctx); 41 static RendererPtr create(SDL_Window* window, bool force_software); 42 SurfaceImplPtr create_texture(int width, int height) override; 43 SurfaceImplPtr create_texture(SDL_Surface_UniquePtr &&surface) override; 44 SurfaceImplPtr create_window_surface(SDL_Window* w, int width, int height) override; 45 ShaderPtr create_shader(const std::string& shader_id) override; 46 ShaderPtr create_shader(const std::string& vertex_source, const std::string& fragment_source, double scaling_factor) override; 47 //void set_render_target(SurfaceImpl& texture) override; 48 void set_render_target(GlTexture* target); 49 void bind_as_gl_target(SurfaceImpl &surf) override; 50 void bind_as_gl_texture(const SurfaceImpl& surf) override; 51 void draw(SurfaceImpl& dst, const SurfaceImpl& src, const DrawInfos& infos) override; 52 void clear(SurfaceImpl& dst) override; 53 void fill(SurfaceImpl& dst, const Color& color, const Rectangle& where, BlendMode mode = BlendMode::BLEND) override; 54 void invalidate(const SurfaceImpl& surf) override; 55 std::string get_name() const override; 56 void present(SDL_Window* window) override; 57 void on_window_size_changed(const Rectangle& viewport) override; get()58 static GlRenderer& get(){ 59 return *instance; 60 } 61 62 const DrawProxy& default_terminal() const override; 63 ~GlRenderer() override; 64 private: 65 static constexpr const char* VCOLOR_ONLY_NAME = "sol_vcolor_only"; 66 void draw(SurfaceImpl& dst, const SurfaceImpl& src, const DrawInfos& infos, GlShader& shader); 67 68 /** 69 * Blend mode aggregate 70 */ 71 using GLBlendMode = std::tuple<GLenum,GLenum,GLenum,GLenum,bool>; 72 73 74 bool use_vao() const; 75 76 void read_pixels(GlTexture* from, void* to); 77 void put_pixels(GlTexture* to, void* data); 78 79 void restart_batch(); 80 void set_shader(GlShader* shader); 81 void set_texture(const GlTexture* texture); 82 void set_state(const GlTexture* src, GlShader* shad, GlTexture* dst, const GLBlendMode& mode, bool force = false); 83 void rebind_texture(); 84 void rebind_shader(); 85 void set_blend_mode(GLBlendMode mode); 86 GLBlendMode make_gl_blend_modes(const GlTexture &dst, const GlTexture *src, BlendMode mode); 87 GLBlendMode make_gl_blend_modes(BlendMode mode); 88 void create_vbo(size_t num_sprites); 89 void add_sprite(const DrawInfos& infos); 90 size_t buffered_indices() const; 91 size_t buffered_vertices() const; 92 Fbo* get_fbo(int width, int height, bool screen = false); 93 94 void shader_about_to_change(GlShader* shader); 95 96 static GlRenderer* instance; 97 SDL_GLContext sdl_gl_context; 98 GlShader* current_shader = nullptr; 99 const GlTexture* current_texture = nullptr; 100 GlTexture* current_target = nullptr; 101 GLBlendMode current_blend_mode = 102 GLBlendMode{GL_ONE,GL_ONE,GL_ONE,GL_ONE,false}; 103 ShaderPtr main_shader; 104 105 GLuint vao = 0; 106 GLuint vbo = 0; 107 GLuint ibo = 0; 108 109 const GlTexture* test_texture = nullptr; 110 111 Vertex* current_vertex = nullptr; 112 size_t buffered_sprites = 0; 113 size_t buffer_size = 0; 114 115 std::vector<Vertex> vertex_buffer; 116 117 Fbo screen_fbo = {0,glm::mat4(1.f)}; 118 std::unordered_map<uint_fast64_t,Fbo> fbos; 119 Rectangle window_viewport; 120 121 bool is_es_context; 122 }; 123 } 124