#pragma once #include "Camera.hpp" #include "Material.hpp" #include "VertexIndex.hpp" #include #include #include #include #include // TODO add optional support for OpenGL separate attrib binding & only depend on vertex format class GameObject; class RenderObject { public: RcPtr autofill_TextureAtlas; private: RcPtr mMaterial; RcPtr mIndexBuf; RcPtr mVertexFormat; BufferBindings mVertexBufBinding; GLuint mVao; public: RenderObject(); ~RenderObject(); GLuint GetGLVao() const; void RebuildIfNecessary(); Material* GetMaterial() const { return mMaterial.Get(); } void SetMaterial(Material* material); GpuIndexBuffer* GetIndexBuffer() const { return mIndexBuf.Get(); } const VertexFormat* GetVertexFormat() const { return mVertexFormat.Get(); } const BufferBindings& GetVertexBufferBindings() const { return mVertexBufBinding; } void UpdateIndexBuffer(GpuIndexBuffer* indexBuffer); void UpdateVertexFormat(VertexFormat* vertexFormat); // Assumes the fetched BufferBinding object is modified void UpdateVertexBufferBindings(BufferBindings** bindingsOut); void SetFormat(VertexFormat* vertexFormat, Tags::IndexType indexFormat); private: void DeleteGLObjects(); }; struct RendererFrameInfo { Camera* camera; glm::mat4 matrixView; glm::mat4 matrixProj; float time; float deltaTime; }; class Renderer { public: // NOTE: see Renderer constructor for default values enum RenderOption { /// Render everything directly using objects' provided material and vertex/index data. RO_Shading, /// Render everything as wireframes using provided position data. RO_Wireframe, RO_COUNT, }; public: RcPtr binding_WireframeMaterial; private: RendererFrameInfo mFrame; bool mInsideFrame = false; bool mRenderOptions[RO_COUNT] = {}; public: Renderer(); void LoadBindings(const rapidjson::Value& bindings); void SaveBindings(rapidjson::Value& into, rapidjson::Document& root) const; void BeginFrame(Camera& camera, float currentTime, float deltaTime); const RendererFrameInfo& GetLastFrameInfo() const { return mFrame; } void Draw(const RenderObject* objects, const GameObject* gameObject, size_t count); void EndFrame(); bool GetRenderOption(RenderOption option) const; void SetRenderOption(RenderOption option, bool flag); };