axmol/extensions/Effekseer/EffekseerRendererGL/EffekseerRenderer/GraphicsDevice.h

414 lines
10 KiB
C++

#ifndef __EFFEKSEERRENDERER_GL_GRAPHICS_DEVICE_H__
#define __EFFEKSEERRENDERER_GL_GRAPHICS_DEVICE_H__
#include "EffekseerRendererGL.GLExtension.h"
#include <Effekseer.h>
#include <assert.h>
#include <functional>
#include <set>
namespace EffekseerRendererGL
{
namespace Backend
{
class GraphicsDevice;
class VertexBuffer;
class IndexBuffer;
class UniformBuffer;
class Shader;
class VertexLayout;
class FrameBuffer;
class Texture;
class RenderPass;
class PipelineState;
class UniformLayout;
using GraphicsDeviceRef = Effekseer::RefPtr<GraphicsDevice>;
using VertexBufferRef = Effekseer::RefPtr<VertexBuffer>;
using IndexBufferRef = Effekseer::RefPtr<IndexBuffer>;
using UniformBufferRef = Effekseer::RefPtr<UniformBuffer>;
using ShaderRef = Effekseer::RefPtr<Shader>;
using VertexLayoutRef = Effekseer::RefPtr<VertexLayout>;
using FrameBufferRef = Effekseer::RefPtr<FrameBuffer>;
using TextureRef = Effekseer::RefPtr<Texture>;
using RenderPassRef = Effekseer::RefPtr<RenderPass>;
using PipelineStateRef = Effekseer::RefPtr<PipelineState>;
using UniformLayoutRef = Effekseer::RefPtr<UniformLayout>;
Effekseer::CustomVector<GLint> GetVertexAttribLocations(const VertexLayoutRef& vertexLayout, const ShaderRef& shader);
void EnableLayouts(const VertexLayoutRef& vertexLayout, const Effekseer::CustomVector<GLint>& locations);
void DisableLayouts(const Effekseer::CustomVector<GLint>& locations);
void StoreUniforms(const ShaderRef& shader, const UniformBufferRef& vertexUniform, const UniformBufferRef& fragmentUniform, bool transpose);
class DeviceObject
{
private:
public:
virtual void OnLostDevice();
virtual void OnResetDevice();
};
/**
@brief VertexBuffer of OpenGL
@note
TODO : Optimize it
*/
class VertexBuffer
: public DeviceObject,
public Effekseer::Backend::VertexBuffer
{
private:
GLuint buffer_ = 0;
std::vector<uint8_t> resources_;
GraphicsDevice* graphicsDevice_ = nullptr;
int32_t size_ = 0;
bool isDynamic_ = false;
public:
VertexBuffer(GraphicsDevice* graphicsDevice);
~VertexBuffer() override;
bool Allocate(int32_t size, bool isDynamic);
void Deallocate();
void OnLostDevice() override;
void OnResetDevice() override;
bool Init(int32_t size, bool isDynamic);
void UpdateData(const void* src, int32_t size, int32_t offset);
GLuint GetBuffer() const
{
return buffer_;
}
};
/**
@brief IndexBuffer of OpenGL
TODO : Optimize it
*/
class IndexBuffer
: public DeviceObject,
public Effekseer::Backend::IndexBuffer
{
private:
GLuint buffer_ = 0;
std::vector<uint8_t> resources_;
GraphicsDevice* graphicsDevice_ = nullptr;
int32_t stride_ = 0;
public:
IndexBuffer(GraphicsDevice* graphicsDevice);
~IndexBuffer() override;
bool Allocate(int32_t elementCount, int32_t stride);
void Deallocate();
void OnLostDevice() override;
void OnResetDevice() override;
bool Init(int32_t elementCount, int32_t stride);
void UpdateData(const void* src, int32_t size, int32_t offset);
GLuint GetBuffer() const
{
return buffer_;
}
};
class UniformBuffer
: public DeviceObject,
public Effekseer::Backend::UniformBuffer
{
private:
Effekseer::CustomVector<uint8_t> buffer_;
public:
UniformBuffer() = default;
~UniformBuffer() override = default;
bool Init(int32_t size, const void* initialData);
const Effekseer::CustomVector<uint8_t>& GetBuffer() const
{
return buffer_;
}
Effekseer::CustomVector<uint8_t>& GetBuffer()
{
return buffer_;
}
void UpdateData(const void* src, int32_t size, int32_t offset);
};
class Texture
: public DeviceObject,
public Effekseer::Backend ::Texture
{
private:
GLuint buffer_ = 0;
GLuint renderbuffer_ = 0;
int32_t target_ = -1;
GraphicsDevice* graphicsDevice_ = nullptr;
std::function<void()> onDisposed_;
public:
Texture(GraphicsDevice* graphicsDevice);
~Texture() override;
bool Init(const Effekseer::Backend::TextureParameter& param, const Effekseer::CustomVector<uint8_t>& initialData);
bool Init(const Effekseer::Backend::RenderTextureParameter& param);
bool Init(const Effekseer::Backend::DepthTextureParameter& param);
bool Init(GLuint buffer, bool hasMipmap, const std::function<void()>& onDisposed);
GLuint GetBuffer() const
{
return buffer_;
}
GLuint GetRenderBuffer() const
{
return renderbuffer_;
}
int32_t GetTarget() const
{
return target_;
}
};
class VertexLayout
: public DeviceObject,
public Effekseer::Backend::VertexLayout
{
private:
Effekseer::CustomVector<Effekseer::Backend::VertexLayoutElement> elements_;
public:
VertexLayout() = default;
~VertexLayout() = default;
bool Init(const Effekseer::Backend::VertexLayoutElement* elements, int32_t elementCount);
const Effekseer::CustomVector<Effekseer::Backend::VertexLayoutElement>& GetElements() const
{
return elements_;
}
};
class Shader
: public DeviceObject,
public Effekseer::Backend::Shader
{
private:
static const size_t elementMax = 16;
GraphicsDevice* graphicsDevice_ = nullptr;
GLuint program_ = 0;
GLuint vao_ = 0;
Effekseer::CustomVector<Effekseer::CustomString<char>> vsCodes_;
Effekseer::CustomVector<Effekseer::CustomString<char>> psCodes_;
Effekseer::Backend::UniformLayoutRef layout_ = nullptr;
Effekseer::CustomVector<GLint> textureLocations_;
Effekseer::CustomVector<GLint> uniformLocations_;
bool Compile();
void Reset();
public:
Shader(GraphicsDevice* graphicsDevice);
~Shader() override;
bool Init(const Effekseer::CustomVector<Effekseer::StringView<char>>& vsCodes, const Effekseer::CustomVector<Effekseer::StringView<char>>& psCodes, Effekseer::Backend::UniformLayoutRef& layout);
void OnLostDevice() override;
void OnResetDevice() override;
GLuint GetProgram() const
{
return program_;
}
GLuint GetVAO() const
{
return vao_;
}
const Effekseer::Backend::UniformLayoutRef& GetLayout() const
{
return layout_;
}
const Effekseer::CustomVector<GLint>& GetTextureLocations() const
{
return textureLocations_;
}
const Effekseer::CustomVector<GLint>& GetUniformLocations() const
{
return uniformLocations_;
}
};
class PipelineState
: public DeviceObject,
public Effekseer::Backend::PipelineState
{
private:
Effekseer::Backend::PipelineStateParameter param_;
Effekseer::CustomVector<GLint> attribLocations_;
public:
PipelineState() = default;
~PipelineState() = default;
bool Init(const Effekseer::Backend::PipelineStateParameter& param);
const Effekseer::Backend::PipelineStateParameter& GetParam() const
{
return param_;
}
const Effekseer::CustomVector<GLint>& GetAttribLocations() const
{
return attribLocations_;
}
};
class RenderPass
: public DeviceObject,
public Effekseer::Backend::RenderPass
{
private:
GLuint buffer_ = 0;
GraphicsDevice* graphicsDevice_ = nullptr;
Effekseer::FixedSizeVector<Effekseer::Backend::TextureRef, Effekseer::Backend::RenderTargetMax> textures_;
Effekseer::Backend::TextureRef depthTexture_;
public:
RenderPass(GraphicsDevice* graphicsDevice);
~RenderPass() override;
bool Init(Effekseer::FixedSizeVector<Effekseer::Backend::TextureRef, Effekseer::Backend::RenderTargetMax>& textures, Effekseer::Backend::TextureRef depthTexture);
const Effekseer::FixedSizeVector<Effekseer::Backend::TextureRef, Effekseer::Backend::RenderTargetMax>& GetTextures() const
{
return textures_;
}
GLuint GetBuffer() const
{
return buffer_;
}
};
enum class DevicePropertyType
{
MaxVaryingVectors,
MaxVertexUniformVectors,
MaxFragmentUniformVectors,
MaxVertexTextureImageUnits,
MaxTextureImageUnits,
};
/**
@brief GraphicsDevice of OpenGL
*/
class GraphicsDevice
: public Effekseer::Backend::GraphicsDevice
{
private:
std::set<DeviceObject*> objects_;
OpenGLDeviceType deviceType_;
std::array<GLuint, Effekseer::TextureSlotMax> samplers_;
GLuint frameBufferTemp_ = 0;
std::map<DevicePropertyType, int> properties_;
bool isValid_ = true;
public:
GraphicsDevice(OpenGLDeviceType deviceType, bool isExtensionsEnabled = true);
~GraphicsDevice() override;
bool GetIsValid() const;
int GetProperty(DevicePropertyType type) const;
void LostDevice();
void ResetDevice();
OpenGLDeviceType GetDeviceType() const;
void Register(DeviceObject* deviceObject);
void Unregister(DeviceObject* deviceObject);
Effekseer::Backend::VertexBufferRef CreateVertexBuffer(int32_t size, const void* initialData, bool isDynamic) override;
Effekseer::Backend::IndexBufferRef CreateIndexBuffer(int32_t elementCount, const void* initialData, Effekseer::Backend::IndexBufferStrideType stride) override;
Effekseer::Backend::TextureRef CreateTexture(const Effekseer::Backend::TextureParameter& param, const Effekseer::CustomVector<uint8_t>& initialData) override;
Effekseer::Backend::TextureRef CreateRenderTexture(const Effekseer::Backend::RenderTextureParameter& param) override;
Effekseer::Backend::TextureRef CreateDepthTexture(const Effekseer::Backend::DepthTextureParameter& param) override;
bool CopyTexture(Effekseer::Backend::TextureRef& dst, Effekseer::Backend::TextureRef& src, const std::array<int, 3>& dstPos, const std::array<int, 3>& srcPos, const std::array<int, 3>& size, int32_t dstLayer, int32_t srcLayer) override;
Effekseer::Backend::UniformBufferRef CreateUniformBuffer(int32_t size, const void* initialData) override;
Effekseer::Backend::VertexLayoutRef CreateVertexLayout(const Effekseer::Backend::VertexLayoutElement* elements, int32_t elementCount) override;
Effekseer::Backend::RenderPassRef CreateRenderPass(Effekseer::FixedSizeVector<Effekseer::Backend::TextureRef, Effekseer::Backend::RenderTargetMax>& textures, Effekseer::Backend::TextureRef& depthTexture) override;
Effekseer::Backend::ShaderRef CreateShaderFromKey(const char* key) override;
Effekseer::Backend::ShaderRef CreateShaderFromCodes(const Effekseer::CustomVector<Effekseer::StringView<char>>& vsCodes, const Effekseer::CustomVector<Effekseer::StringView<char>>& psCodes, Effekseer::Backend::UniformLayoutRef layout) override;
Effekseer::Backend::PipelineStateRef CreatePipelineState(const Effekseer::Backend::PipelineStateParameter& param) override;
void Draw(const Effekseer::Backend::DrawParameter& drawParam) override;
void SetViewport(int32_t x, int32_t y, int32_t width, int32_t height) override;
void BeginRenderPass(Effekseer::Backend::RenderPassRef& renderPass, bool isColorCleared, bool isDepthCleared, Effekseer::Color clearColor) override;
void EndRenderPass() override;
bool UpdateUniformBuffer(Effekseer::Backend::UniformBufferRef& buffer, int32_t size, int32_t offset, const void* data) override;
std::string GetDeviceName() const override
{
return "OpenGL";
}
Effekseer::Backend::TextureRef CreateTexture(GLuint buffer, bool hasMipmap, const std::function<void()>& onDisposed);
};
} // namespace Backend
} // namespace EffekseerRendererGL
#endif