NazaraEngine/include/Nazara/OpenGLRenderer/Wrapper/Context.hpp

298 lines
8.5 KiB
C++

// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - OpenGL renderer"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OPENGLRENDERER_WRAPPER_CONTEXT_HPP
#define NAZARA_OPENGLRENDERER_WRAPPER_CONTEXT_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RenderStates.hpp>
#include <NazaraUtils/EnumArray.hpp>
#include <NazaraUtils/StringHash.hpp>
#include <array>
#include <string>
#include <unordered_set>
namespace Nz
{
class OpenGLDevice;
class OpenGLTexture;
}
namespace Nz::GL
{
class Framebuffer;
class Texture;
enum class BufferTarget
{
Array,
CopyRead,
CopyWrite,
ElementArray,
PixelPack,
PixelUnpack,
Storage,
TransformFeedback,
Uniform,
Max = Uniform
};
enum class ContextType
{
OpenGL,
OpenGL_ES
};
enum class Extension
{
ClipControl,
ComputeShader,
DebugOutput,
DepthClamp,
PolygonMode,
ShaderImageLoadFormatted,
ShaderImageLoadStore,
SpirV,
StorageBuffers,
TextureCompressionS3tc,
TextureFilterAnisotropic,
TextureView,
Max = TextureView
};
enum class ExtensionStatus
{
NotSupported = 0,
ARB = 3,
Core = 5,
EXT = 2,
KHR = 4,
Vendor = 1
};
enum class FramebufferTarget
{
Draw,
Read
};
enum class TextureTarget
{
Cubemap,
CubemapNegativeX,
CubemapNegativeY,
CubemapNegativeZ,
CubemapPositiveX,
CubemapPositiveY,
CubemapPositiveZ,
Target2D,
Target2D_Array,
Target3D,
Max = Target3D
};
struct ContextParams
{
ContextType type = ContextType::OpenGL_ES;
RenderAPIValidationLevel validationLevel = RenderAPIValidationLevel::Warnings;
bool doubleBuffering = true;
bool wrapErrorHandling = false;
unsigned int bitsPerPixel = 32;
unsigned int depthBits = 24;
unsigned int glMajorVersion = 0;
unsigned int glMinorVersion = 0;
unsigned int sampleCount = 1;
unsigned int stencilBits = 8;
};
class NAZARA_OPENGLRENDERER_API Context
{
struct SymbolLoader;
friend SymbolLoader;
public:
Context(const OpenGLDevice* device);
Context(const Context&) = delete;
Context(Context&&) = delete;
virtual ~Context();
void BindBuffer(BufferTarget target, GLuint buffer, bool force = false) const;
[[nodiscard]] GLenum BindFramebuffer(GLuint fbo) const;
void BindFramebuffer(FramebufferTarget target, GLuint fbo) const;
void BindImageTexture(GLuint imageUnit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) const;
void BindProgram(GLuint program) const;
void BindSampler(UInt32 textureUnit, GLuint sampler) const;
void BindStorageBuffer(UInt32 storageUnit, GLuint buffer, GLintptr offset, GLsizeiptr size) const;
void BindTexture(TextureTarget target, GLuint texture) const;
void BindTexture(UInt32 textureUnit, TextureTarget target, GLuint texture) const;
void BindUniformBuffer(UInt32 uboUnit, GLuint buffer, GLintptr offset, GLsizeiptr size) const;
void BindVertexArray(GLuint vertexArray, bool force = false) const;
bool BlitTexture(const OpenGLTexture& source, const OpenGLTexture& destination, const Boxui& srcBox, const Boxui& dstBox, SamplerFilter filter) const;
bool BlitTextureToWindow(const OpenGLTexture& texture, const Boxui& srcBox, const Boxui& dstBox, SamplerFilter filter) const;
bool ClearErrorStack() const;
bool CopyTexture(const OpenGLTexture& source, const OpenGLTexture& destination, const Boxui& srcBox, const Vector3ui& dstPos) const;
inline bool DidLastCallSucceed() const;
inline bool GetBoolean(GLenum name) const;
inline bool GetBoolean(GLenum name, GLuint index) const;
inline const OpenGLDevice* GetDevice() const;
inline ExtensionStatus GetExtensionStatus(Extension extension) const;
inline float GetFloat(GLenum name) const;
inline GLFunction GetFunctionByIndex(std::size_t funcIndex) const;
template<typename T> T GetInteger(GLenum name) const;
template<typename T> T GetInteger(GLenum name, GLuint index) const;
inline const ContextParams& GetParams() const;
virtual PresentModeFlags GetSupportedPresentModes() const = 0;
inline const OpenGLVaoCache& GetVaoCache() const;
inline bool IsExtensionSupported(Extension extension) const;
inline bool IsExtensionSupported(std::string_view extension) const;
inline bool HasZeroToOneDepth() const;
bool Initialize(const ContextParams& params);
inline void NotifyBufferDestruction(GLuint buffer) const;
inline void NotifyFramebufferDestruction(GLuint fbo) const;
inline void NotifyProgramDestruction(GLuint program) const;
inline void NotifySamplerDestruction(GLuint sampler) const;
inline void NotifyTextureDestruction(GLuint texture) const;
inline void NotifyVertexArrayDestruction(GLuint vao) const;
template<typename... Args> void PrintFunctionCall(std::size_t funcIndex, Args... args) const;
bool ProcessErrorStack() const;
inline void ResetColorWriteMasks() const;
inline void ResetDepthWriteMasks() const;
inline void ResetStencilWriteMasks() const;
void SetCurrentTextureUnit(UInt32 textureUnit) const;
virtual void SetPresentMode(PresentMode presentMode) = 0;
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
virtual void SwapBuffers() = 0;
void UpdateStates(const RenderStates& renderStates, bool isViewportFlipped) const;
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) sig name = nullptr;
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_FUNC)
#undef NAZARA_OPENGLRENDERER_FUNC
Context& operator=(const Context&) = delete;
Context& operator=(Context&&) = delete;
static const Context* GetCurrentContext();
static bool SetCurrentContext(const Context* context);
NazaraSignal(OnContextDestruction, Context* /*context*/);
protected:
virtual bool Activate() const = 0;
virtual void Desactivate() const = 0;
virtual const Loader& GetLoader() = 0;
void OnContextRelease();
virtual bool ImplementFallback(std::string_view function);
static void NotifyContextDestruction(Context* context);
ContextParams m_params;
private:
void HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message) const;
bool InitializeBlitFramebuffers() const;
static void BindTextureToFramebuffer(Framebuffer& framebuffer, const OpenGLTexture& texture);
enum class FunctionIndex
{
#define NAZARA_OPENGLRENDERER_FUNC(name, sig) name,
NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(NAZARA_OPENGLRENDERER_FUNC, NAZARA_OPENGLRENDERER_FUNC)
#undef NAZARA_OPENGLRENDERER_FUNC
Count
};
struct BlitFramebuffers;
struct State
{
struct Box
{
GLint x, y;
GLsizei width, height;
};
struct BufferBinding
{
GLuint buffer = 0;
GLintptr offset = 0;
GLsizeiptr size = 0;
};
struct ImageUnits
{
GLboolean layered = GL_FALSE;
GLenum access = GL_READ_ONLY;
GLenum format = GL_RGBA8;
GLint layer = 0;
GLint level = 0;
GLuint texture = 0;
};
struct TextureUnit
{
GLuint sampler = 0;
EnumArray<TextureTarget, GLuint> textureTargets = { 0 };
};
EnumArray<BufferTarget, GLuint> bufferTargets = { 0 };
std::vector<BufferBinding> storageUnits;
std::vector<BufferBinding> uboUnits;
std::vector<ImageUnits> imageUnits;
std::vector<TextureUnit> textureUnits;
Box scissorBox;
Box viewport;
GLuint boundProgram = 0;
GLuint boundDrawFBO = 0;
GLuint boundReadFBO = 0;
GLuint boundVertexArray = 0;
UInt32 currentTextureUnit = 0;
RenderStates renderStates;
};
EnumArray<Extension, ExtensionStatus> m_extensionStatus;
std::array<GLFunction, UnderlyingCast(FunctionIndex::Count)> m_originalFunctionPointer;
mutable std::unique_ptr<BlitFramebuffers> m_blitFramebuffers;
std::unordered_set<std::string, StringHash<>, std::equal_to<>> m_supportedExtensions;
OpenGLVaoCache m_vaoCache;
const OpenGLDevice* m_device;
mutable State m_state;
mutable bool m_didCollectErrors;
mutable bool m_hadAnyError;
bool m_hasZeroToOneDepth;
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Context.inl>
#endif // NAZARA_OPENGLRENDERER_WRAPPER_CONTEXT_HPP