hyporo-cpp/source/hyporo/gpu/device.cpp

152 lines
3.4 KiB
C++
Raw Normal View History

2022-10-03 18:51:34 +05:00
#include "device.hpp"
#include "opengl/device.hpp"
namespace hpr::gpu
{
2022-10-05 21:10:51 +05:00
Device::Device() :
Context {DeviceAPI::Unknown},
p_currentVertexBuffer {nullptr},
p_currentIndexBuffer {nullptr},
p_currentShaderProgram {nullptr}
{}
2022-10-03 18:51:34 +05:00
2022-10-05 21:10:51 +05:00
Device::Device(DeviceAPI api) :
Context {api},
p_currentVertexBuffer {nullptr},
p_currentIndexBuffer {nullptr},
p_currentShaderProgram {nullptr}
{}
2022-10-03 18:51:34 +05:00
2022-10-05 21:10:51 +05:00
Device::~Device()
{}
2022-10-03 18:51:34 +05:00
2022-10-05 21:10:51 +05:00
// Global functions
void Device::create(Device** device, DeviceAPI api)
{
if (device == nullptr)
throw "Invalid parameter";
if (api == DeviceAPI::Unknown)
throw "Invalid parameter";
*device = nullptr;
if (api == DeviceAPI::OpenGL)
*device = new opengl::Device;
else
throw "Unsupported device";
}
2022-10-03 18:51:34 +05:00
2022-10-05 21:10:51 +05:00
// Buffers
void Device::useVertexBuffer(Buffer* buffer, int stride, int offset)
{
if (buffer)
{
if (buffer->p_type == Buffer::BufferType::Vertex)
{
p_currentVertexBuffer = buffer;
p_currentVertexBuffer->p_stride = stride;
}
else
throw "Incompatible buffer";
}
else
p_currentVertexBuffer = nullptr;
}
2022-10-03 18:51:34 +05:00
2022-10-05 21:10:51 +05:00
void Device::useIndexBuffer(Buffer* buffer, int offset)
{
if (buffer)
{
if (buffer->p_type == Buffer::BufferType::Index)
{
p_currentIndexBuffer = buffer;
}
2022-10-03 18:51:34 +05:00
else
2022-10-05 21:10:51 +05:00
throw "Incompatible buffer";
2022-10-03 18:51:34 +05:00
}
2022-10-05 21:10:51 +05:00
else
p_currentIndexBuffer = nullptr;
}
void Device::destroyBuffer(Buffer*& buffer)
{
if (!buffer)
throw "Invalid parameter";
for (auto iter = p_buffers.begin(); iter != p_buffers.end(); ++iter)
if (&*iter == &*buffer)
p_buffers.erase(iter);
buffer = nullptr;
}
// Shaders
void Device::destroyShader(Shader *&shader)
{
if (shader == nullptr)
throw "Invalid parameter";
for (auto iter = p_shaders.begin(); iter != p_shaders.end(); ++iter)
if (&*iter == &*shader)
p_shaders.erase(iter);
shader = nullptr;
}
// Shader programs
void Device::attachShader(ShaderProgram *program, Shader *shader)
{
if (program == nullptr || shader == nullptr)
throw "Invalid parameter";
if (program->p_isLinked)
throw "Shader program already linked";
program->p_slots[(int)shader->p_type] = shader;
}
void Device::linkProgram(ShaderProgram *program)
{
if (program == nullptr)
throw "Invalid parameter";
if (program->p_isLinked)
throw "Shader program already linked";
program->p_isLinked = true;
}
void Device::useShaderProgram(ShaderProgram *program)
{
if (program != nullptr)
if (!program->p_isLinked)
throw "Shader program is not linked";
p_currentShaderProgram = program;
}
void Device::destroyShaderProgram(ShaderProgram *&program, bool withShaders)
{
if (program == p_currentShaderProgram)
useShaderProgram(nullptr);
if (withShaders)
for (size_t n = 0; n < (size_t)Shader::ShaderType::ShaderTypeCount; n++)
destroyShader(program->p_slots[n]);
program = nullptr;
}
// Textures
void Device::destroyTexture(Texture *&texture)
{
for (auto iter = p_textures.begin(); iter != p_textures.end(); ++iter)
if (&*iter == &*texture)
p_textures.erase(iter);
texture = nullptr;
}
2022-10-03 18:51:34 +05:00
}