axmol/extensions/Effekseer/EffekseerRendererLLGI/GraphicsDevice.cpp

420 lines
9.7 KiB
C++

#include "GraphicsDevice.h"
#include <LLGI.Shader.h>
#include <LLGI.Texture.h>
namespace EffekseerRendererLLGI
{
namespace Backend
{
void DeviceObject::OnLostDevice()
{
}
void DeviceObject::OnResetDevice()
{
}
VertexBuffer::VertexBuffer(GraphicsDevice* graphicsDevice)
: graphicsDevice_(graphicsDevice)
{
ES_SAFE_ADDREF(graphicsDevice_);
graphicsDevice_->Register(this);
}
VertexBuffer::~VertexBuffer()
{
graphicsDevice_->Unregister(this);
ES_SAFE_RELEASE(graphicsDevice_);
}
bool VertexBuffer::Allocate(int32_t size, bool isDynamic)
{
buffer_ = LLGI::CreateSharedPtr(graphicsDevice_->GetGraphics()->CreateBuffer(LLGI::BufferUsageType::Vertex | LLGI::BufferUsageType::MapWrite, size));
return true;
}
void VertexBuffer::Deallocate()
{
buffer_.reset();
}
void VertexBuffer::OnLostDevice()
{
Deallocate();
}
void VertexBuffer::OnResetDevice()
{
Allocate(size_, isDynamic_);
}
bool VertexBuffer::Init(int32_t size, bool isDynamic)
{
size_ = size;
isDynamic_ = isDynamic;
return Allocate(size_, isDynamic_);
}
void VertexBuffer::UpdateData(const void* src, int32_t size, int32_t offset)
{
if (auto dst = static_cast<uint8_t*>(buffer_->Lock()))
{
memcpy(dst + offset, src, size);
buffer_->Unlock();
}
}
IndexBuffer::IndexBuffer(GraphicsDevice* graphicsDevice)
: graphicsDevice_(graphicsDevice)
{
ES_SAFE_ADDREF(graphicsDevice_);
graphicsDevice_->Register(this);
}
IndexBuffer::~IndexBuffer()
{
graphicsDevice_->Unregister(this);
ES_SAFE_RELEASE(graphicsDevice_);
}
bool IndexBuffer::Allocate(int32_t elementCount, int32_t stride)
{
buffer_ = LLGI::CreateSharedPtr(graphicsDevice_->GetGraphics()->CreateBuffer(LLGI::BufferUsageType::Index | LLGI::BufferUsageType::MapWrite, stride * elementCount));
elementCount_ = elementCount;
strideType_ = stride == 4 ? Effekseer::Backend::IndexBufferStrideType::Stride4 : Effekseer::Backend::IndexBufferStrideType::Stride2;
return buffer_ != nullptr;
}
void IndexBuffer::Deallocate()
{
buffer_.reset();
}
void IndexBuffer::OnLostDevice()
{
Deallocate();
}
void IndexBuffer::OnResetDevice()
{
Allocate(elementCount_, stride_);
}
bool IndexBuffer::Init(int32_t elementCount, int32_t stride)
{
elementCount_ = elementCount;
stride_ = stride;
return Allocate(elementCount_, stride_);
}
void IndexBuffer::UpdateData(const void* src, int32_t size, int32_t offset)
{
if (auto dst = static_cast<uint8_t*>(buffer_->Lock()))
{
memcpy(dst + offset, src, size);
buffer_->Unlock();
}
}
Texture::Texture(GraphicsDevice* graphicsDevice)
: graphicsDevice_(graphicsDevice)
{
ES_SAFE_ADDREF(graphicsDevice_);
graphicsDevice_->Register(this);
}
Texture::~Texture()
{
if (onDisposed_)
{
onDisposed_();
}
graphicsDevice_->Unregister(this);
ES_SAFE_RELEASE(graphicsDevice_);
}
bool Texture::Init(const Effekseer::Backend::TextureParameter& param, const Effekseer::CustomVector<uint8_t>& initialData)
{
int mw = std::max(param.Size[0], param.Size[1]);
int count = 1;
while (mw > 1)
{
mw = mw << 1;
count++;
}
LLGI::TextureInitializationParameter texParam;
texParam.Size = LLGI::Vec2I(param.Size[0], param.Size[1]);
texParam.MipMapCount = param.MipLevelCount < 1 ? count : param.MipLevelCount;
// TODO : Fix it
texParam.MipMapCount = 1;
LLGI::TextureFormatType format = LLGI::TextureFormatType::R8G8B8A8_UNORM;
if (param.Format == Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM)
{
texParam.Format = LLGI::TextureFormatType::R8G8B8A8_UNORM;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::B8G8R8A8_UNORM)
{
texParam.Format = LLGI::TextureFormatType::B8G8R8A8_UNORM;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::R8_UNORM)
{
texParam.Format = LLGI::TextureFormatType::R8_UNORM;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::R16G16_FLOAT)
{
texParam.Format = LLGI::TextureFormatType::R16G16_FLOAT;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::R16G16B16A16_FLOAT)
{
texParam.Format = LLGI::TextureFormatType::R16G16B16A16_FLOAT;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::R32G32B32A32_FLOAT)
{
texParam.Format = LLGI::TextureFormatType::R32G32B32A32_FLOAT;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC1)
{
texParam.Format = LLGI::TextureFormatType::BC1;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC2)
{
texParam.Format = LLGI::TextureFormatType::BC2;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC3)
{
texParam.Format = LLGI::TextureFormatType::BC3;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM_SRGB)
{
texParam.Format = LLGI::TextureFormatType::R8G8B8A8_UNORM_SRGB;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::B8G8R8A8_UNORM_SRGB)
{
texParam.Format = LLGI::TextureFormatType::B8G8R8A8_UNORM_SRGB;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC1_SRGB)
{
texParam.Format = LLGI::TextureFormatType::BC1_SRGB;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC2_SRGB)
{
texParam.Format = LLGI::TextureFormatType::BC2_SRGB;
}
else if (param.Format == Effekseer::Backend::TextureFormatType::BC3_SRGB)
{
texParam.Format = LLGI::TextureFormatType::BC3_SRGB;
}
else
{
// not supported
Effekseer::Log(Effekseer::LogType::Error, "The format is not supported.(" + std::to_string(static_cast<int>(param.Format)) + ")");
return false;
}
auto texture = graphicsDevice_->GetGraphics()->CreateTexture(texParam);
auto buf = texture->Lock();
if (initialData.size() > 0)
{
memcpy(buf, initialData.data(), initialData.size());
}
texture->Unlock();
texture_ = LLGI::CreateSharedPtr(texture);
param_ = param;
return true;
}
bool Texture::Init(uint64_t id, std::function<void()> onDisposed)
{
auto texture = graphicsDevice_->GetGraphics()->CreateTexture(id);
if (texture == nullptr)
{
return false;
}
texture_ = LLGI::CreateSharedPtr(texture);
onDisposed_ = onDisposed;
param_.Format = Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM;
param_.Dimension = 2;
param_.Size = {
texture->GetSizeAs2D().X,
texture->GetSizeAs2D().Y,
0};
param_.MipLevelCount = texture_->GetMipmapCount();
param_.SampleCount = texture_->GetSamplingCount();
param_.Usage = Effekseer::Backend::TextureUsageType::External;
return true;
}
bool Texture::Init(LLGI::Texture* texture)
{
LLGI::SafeAddRef(texture);
texture_ = LLGI::CreateSharedPtr(texture);
param_.Format = Effekseer::Backend::TextureFormatType::R8G8B8A8_UNORM;
param_.Dimension = 2;
param_.Size = {
texture->GetSizeAs2D().X,
texture->GetSizeAs2D().Y,
0};
param_.MipLevelCount = texture_->GetMipmapCount();
param_.SampleCount = texture_->GetSamplingCount();
param_.Usage = Effekseer::Backend::TextureUsageType::External;
return true;
}
Shader::Shader(GraphicsDevice* graphicsDevice)
: graphicsDevice_(graphicsDevice)
{
ES_SAFE_ADDREF(graphicsDevice_);
graphicsDevice_->Register(this);
}
Shader ::~Shader()
{
Effekseer::SafeRelease(vertexShader_);
Effekseer::SafeRelease(pixelShader_);
graphicsDevice_->Unregister(this);
Effekseer::SafeRelease(graphicsDevice_);
}
bool Shader::Init(const void* vertexShaderData, int32_t vertexShaderDataSize, const void* pixelShaderData, int32_t pixelShaderDataSize)
{
// TODO
return false;
}
GraphicsDevice::GraphicsDevice(LLGI::Graphics* graphics)
: graphics_(graphics)
{
ES_SAFE_ADDREF(graphics_);
}
GraphicsDevice::~GraphicsDevice()
{
ES_SAFE_RELEASE(graphics_);
}
void GraphicsDevice::LostDevice()
{
for (auto& o : objects_)
{
o->OnLostDevice();
}
}
void GraphicsDevice::ResetDevice()
{
for (auto& o : objects_)
{
o->OnResetDevice();
}
}
LLGI::Graphics* GraphicsDevice::GetGraphics()
{
return graphics_;
}
void GraphicsDevice::Register(DeviceObject* deviceObject)
{
objects_.insert(deviceObject);
}
void GraphicsDevice::Unregister(DeviceObject* deviceObject)
{
objects_.erase(deviceObject);
}
Effekseer::Backend::VertexBufferRef GraphicsDevice::CreateVertexBuffer(int32_t size, const void* initialData, bool isDynamic)
{
auto ret = Effekseer::MakeRefPtr<VertexBuffer>(this);
if (!ret->Init(size, isDynamic))
{
return nullptr;
}
ret->UpdateData(initialData, size, 0);
return ret;
}
Effekseer::Backend::IndexBufferRef GraphicsDevice::CreateIndexBuffer(int32_t elementCount, const void* initialData, Effekseer::Backend::IndexBufferStrideType stride)
{
auto ret = Effekseer::MakeRefPtr<IndexBuffer>(this);
if (!ret->Init(elementCount, stride == Effekseer::Backend::IndexBufferStrideType::Stride4 ? 4 : 2))
{
return nullptr;
}
ret->UpdateData(initialData, elementCount * (stride == Effekseer::Backend::IndexBufferStrideType::Stride4 ? 4 : 2), 0);
return ret;
}
Effekseer::Backend::TextureRef GraphicsDevice::CreateTexture(const Effekseer::Backend::TextureParameter& param, const Effekseer::CustomVector<uint8_t>& initialData)
{
auto ret = Effekseer::MakeRefPtr<Texture>(this);
if (!ret->Init(param, initialData))
{
return nullptr;
}
return ret;
}
Effekseer::Backend::TextureRef GraphicsDevice::CreateTexture(uint64_t id, const std::function<void()>& onDisposed)
{
auto ret = Effekseer::MakeRefPtr<Texture>(this);
if (!ret->Init(id, onDisposed))
{
return nullptr;
}
return ret;
}
Effekseer::Backend::TextureRef GraphicsDevice::CreateTexture(LLGI::Texture* texture)
{
auto ret = Effekseer::MakeRefPtr<Texture>(this);
if (!ret->Init(texture))
{
return nullptr;
}
return ret;
}
Effekseer::Backend::ShaderRef GraphicsDevice::CreateShaderFromBinary(const void* vsData, int32_t vsDataSize, const void* psData, int32_t psDataSize)
{
auto ret = Effekseer::MakeRefPtr<Shader>(this);
if (!ret->Init(vsData, vsDataSize, psData, psDataSize))
{
return nullptr;
}
return ret;
}
} // namespace Backend
} // namespace EffekseerRendererLLGI