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
|
|
|
}
|