/* ** BuilderNative Renderer ** Copyright (c) 2019 Magnus Norddahl ** ** This software is provided 'as-is', without any express or implied ** warranty. In no event will the authors be held liable for any damages ** arising from the use of this software. ** ** Permission is granted to anyone to use this software for any purpose, ** including commercial applications, and to alter it and redistribute it ** freely, subject to the following restrictions: ** ** 1. The origin of this software must not be misrepresented; you must not ** claim that you wrote the original software. If you use this software ** in a product, an acknowledgment in the product documentation would be ** appreciated but is not required. ** 2. Altered source versions must be plainly marked as such, and must not be ** misrepresented as being the original software. ** 3. This notice may not be removed or altered from any source distribution. */ #pragma once #include "../Backend.h" #include "OpenGLContext.h" #include class GLSharedVertexBuffer; class GLShader; class GLShaderManager; class GLVertexBuffer; class GLIndexBuffer; class GLTexture; class GLRenderDevice : public RenderDevice { public: GLRenderDevice(void* disp, void* window, bool debug); ~GLRenderDevice(); void DeclareUniform(UniformName name, const char* glslname, UniformType type) override; void DeclareShader(ShaderName index, const char* name, const char* vertexshader, const char* fragmentshader) override; void SetShader(ShaderName name) override; void SetUniform(UniformName name, const void* values, int count, int bytesize) override; void SetVertexBuffer(VertexBuffer* buffer) override; void SetIndexBuffer(IndexBuffer* buffer) override; void SetAlphaBlendEnable(bool value) override; void SetAlphaTestEnable(bool value) override; void SetCullMode(Cull mode) override; void SetBlendOperation(BlendOperation op) override; void SetSourceBlend(Blend blend) override; void SetDestinationBlend(Blend blend) override; void SetFillMode(FillMode mode) override; void SetMultisampleAntialias(bool value) override; void SetZEnable(bool value) override; void SetZWriteEnable(bool value) override; void SetTexture(int unit, Texture* texture) override; void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, MipmapFilter mipfilter, float maxanisotropy) override; void SetSamplerState(int unit, TextureAddress address) override; bool Draw(PrimitiveType type, int startIndex, int primitiveCount) override; bool DrawIndexed(PrimitiveType type, int startIndex, int primitiveCount) override; bool DrawData(PrimitiveType type, int startIndex, int primitiveCount, const void* data) override; bool StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer) override; bool FinishRendering() override; bool Present() override; bool ClearTexture(int backcolor, Texture* texture) override; bool CopyTexture(Texture* dst, CubeMapFace face) override; bool SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format) override; bool SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) override; bool SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size) override; bool SetPixels(Texture* texture, const void* data) override; bool SetCubePixels(Texture* texture, CubeMapFace face, const void* data) override; void* MapPBO(Texture* texture) override; bool UnmapPBO(Texture* texture) override; bool InvalidateTexture(GLTexture* texture); void GarbageCollectBuffer(int size, VertexFormat format); bool ApplyViewport(); bool ApplyChanges(); bool ApplyVertexBuffer(); bool ApplyIndexBuffer(); bool ApplyShader(); bool ApplyUniforms(); bool ApplyTextures(); bool ApplyRasterizerState(); bool ApplyBlendState(); bool ApplyDepthState(); void CheckContext(); void RequireContext(); bool CheckGLError(); GLShader* GetActiveShader(); GLint GetGLMinFilter(TextureFilter filter, MipmapFilter mipfilter); static std::mutex& GetMutex(); static void DeleteObject(GLVertexBuffer* buffer); static void DeleteObject(GLIndexBuffer* buffer); static void DeleteObject(GLTexture* texture); void ProcessDeleteList(bool finalize = false); std::unique_ptr Context; struct DeleteList { std::vector VertexBuffers; std::vector IndexBuffers; std::vector Textures; } mDeleteList; struct TextureUnit { GLTexture* Tex = nullptr; TextureAddress WrapMode = TextureAddress::Wrap; GLuint SamplerHandle = 0; TextureFilter MinFilter = TextureFilter::Nearest; TextureFilter MagFilter = TextureFilter::Nearest; MipmapFilter MipFilter = MipmapFilter::None; float MaxAnisotropy = 1; } mTextureUnit[10]; struct SamplerFilterKey { GLuint MinFilter = 0; GLuint MagFilter = 0; float MaxAnisotropy = 0.0f; bool operator<(const SamplerFilterKey& b) const { return memcmp(this, &b, sizeof(SamplerFilterKey)) < 0; } bool operator==(const SamplerFilterKey& b) const { return memcmp(this, &b, sizeof(SamplerFilterKey)) == 0; } bool operator!=(const SamplerFilterKey& b) const { return memcmp(this, &b, sizeof(SamplerFilterKey)) != 0; } }; struct SamplerFilter { GLuint WrapModes[2] = { 0, 0 }; }; std::map mSamplers; SamplerFilterKey GetSamplerFilterKey(TextureFilter filter, MipmapFilter mipFilter, float maxAnisotropy); int mVertexBuffer = -1; int64_t mVertexBufferStartIndex = 0; GLIndexBuffer* mIndexBuffer = nullptr; std::unique_ptr mSharedVertexBuffers[2]; std::list mTextures; std::list mIndexBuffers; std::unique_ptr mShaderManager; ShaderName mShaderName = {}; struct UniformInfo { std::string Name; UniformType Type = {}; int LastUpdate = 0; int Count = 0; std::vector Data; }; std::vector mUniformInfo; GLuint mStreamVertexBuffer = 0; GLuint mStreamVAO = 0; Cull mCullMode = Cull::None; FillMode mFillMode = FillMode::Solid; bool mAlphaTest = false; bool mAlphaBlend = false; BlendOperation mBlendOperation = BlendOperation::Add; Blend mSourceBlend = Blend::SourceAlpha; Blend mDestinationBlend = Blend::InverseSourceAlpha; bool mDepthTest = false; bool mDepthWrite = false; bool mNeedApply = true; bool mShaderChanged = true; bool mUniformsChanged = true; bool mTexturesChanged = true; bool mIndexBufferChanged = true; bool mVertexBufferChanged = true; bool mDepthStateChanged = true; bool mBlendStateChanged = true; bool mRasterizerStateChanged = true; bool mContextIsCurrent = false; int mViewportWidth = 0; int mViewportHeight = 0; };