opengl
This commit is contained in:
parent
0aabe8ffac
commit
f43b2f4b44
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ build/
|
|||||||
.ccls-cache/
|
.ccls-cache/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.cache/
|
.cache/
|
||||||
|
temp/
|
||||||
|
@ -17,6 +17,8 @@ if(WITH_GTESTS)
|
|||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
include(${CMAKE_SOURCE_DIR}/cmake/glad.cmake)
|
||||||
add_definitions(-DPRECISION_FLOAT)
|
add_definitions(-DPRECISION_FLOAT)
|
||||||
|
|
||||||
add_subdirectory(source)
|
add_subdirectory(source)
|
||||||
|
9
cmake/glad.cmake
Normal file
9
cmake/glad.cmake
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME glad
|
||||||
|
GIT_REPOSITORY https://github.com/Dav1dde/glad.git
|
||||||
|
VERSION 0.1.36
|
||||||
|
GIT_PROGRESS TRUE
|
||||||
|
OPTIONS "GLAD_EXPORT ON" "GLAD_INSTALL ON"
|
||||||
|
)
|
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
include_directories(
|
||||||
|
../hyplib
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(hyporo-gpu STATIC
|
||||||
|
# Source files
|
||||||
|
buffer.cpp
|
||||||
|
context.cpp
|
||||||
|
shader.cpp
|
||||||
|
opengl/buffer.cpp
|
||||||
|
opengl/context.cpp
|
||||||
|
opengl/shader.cpp
|
||||||
|
opengl/texture.cpp
|
||||||
|
opengl/device.cpp
|
||||||
|
opengl/shader_program.cpp
|
||||||
|
texture.cpp
|
||||||
|
device.cpp
|
||||||
|
shader_program.cpp
|
||||||
|
|
||||||
|
# Header files
|
||||||
|
context.hpp
|
||||||
|
shader.hpp
|
||||||
|
shader_program.hpp
|
||||||
|
buffer.hpp
|
||||||
|
device.hpp
|
||||||
|
texture.hpp
|
||||||
|
opengl/context.hpp
|
||||||
|
opengl/shader.hpp
|
||||||
|
opengl/shader_program.hpp
|
||||||
|
opengl/buffer.hpp
|
||||||
|
opengl/device.hpp
|
||||||
|
opengl/texture.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(hyporo-gpu
|
||||||
|
glad
|
||||||
|
hyporo-hyplib
|
||||||
|
)
|
@ -22,7 +22,14 @@ Buffer::Buffer(DeviceAPI api) :
|
|||||||
Buffer::~Buffer()
|
Buffer::~Buffer()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const BufferType Buffer::type() const
|
// Member functions
|
||||||
|
|
||||||
|
int Buffer::size() const
|
||||||
|
{
|
||||||
|
return p_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::BufferType Buffer::type() const
|
||||||
{
|
{
|
||||||
return p_type;
|
return p_type;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ namespace hpr::gpu
|
|||||||
|
|
||||||
class Buffer : public Context
|
class Buffer : public Context
|
||||||
{
|
{
|
||||||
|
friend class Device;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -39,9 +40,9 @@ public:
|
|||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
|
||||||
const int size() const;
|
int size() const;
|
||||||
|
|
||||||
const BufferType type() const;
|
BufferType type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace hpr::gpu
|
} // end namespace hpr::gpu
|
@ -6,29 +6,147 @@
|
|||||||
namespace hpr::gpu
|
namespace hpr::gpu
|
||||||
{
|
{
|
||||||
|
|
||||||
Device::Device() :
|
Device::Device() :
|
||||||
Context {DeviceAPI::Unknown}
|
Context {DeviceAPI::Unknown},
|
||||||
{}
|
p_currentVertexBuffer {nullptr},
|
||||||
|
p_currentIndexBuffer {nullptr},
|
||||||
|
p_currentShaderProgram {nullptr}
|
||||||
|
{}
|
||||||
|
|
||||||
Device::Device(DeviceAPI api) :
|
Device::Device(DeviceAPI api) :
|
||||||
Context {api}
|
Context {api},
|
||||||
{}
|
p_currentVertexBuffer {nullptr},
|
||||||
|
p_currentIndexBuffer {nullptr},
|
||||||
|
p_currentShaderProgram {nullptr}
|
||||||
|
{}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Device::create(Device **device, DeviceAPI api)
|
// 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffers
|
||||||
|
|
||||||
|
void Device::useVertexBuffer(Buffer* buffer, int stride, int offset)
|
||||||
|
{
|
||||||
|
if (buffer)
|
||||||
{
|
{
|
||||||
if (device == nullptr)
|
if (buffer->p_type == Buffer::BufferType::Vertex)
|
||||||
throw "Invalid parameter";
|
{
|
||||||
if (api == DeviceAPI::Unknown)
|
p_currentVertexBuffer = buffer;
|
||||||
throw "Invalid parameter";
|
p_currentVertexBuffer->p_stride = stride;
|
||||||
|
}
|
||||||
*device = nullptr;
|
|
||||||
|
|
||||||
if (api == DeviceAPI::OpenGL)
|
|
||||||
*device = new opengl::Device;
|
|
||||||
else
|
else
|
||||||
throw "Unsupported device";
|
throw "Incompatible buffer";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
p_currentVertexBuffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::useIndexBuffer(Buffer* buffer, int offset)
|
||||||
|
{
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
if (buffer->p_type == Buffer::BufferType::Index)
|
||||||
|
{
|
||||||
|
p_currentIndexBuffer = buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw "Incompatible buffer";
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,6 +21,7 @@ public:
|
|||||||
{
|
{
|
||||||
Front,
|
Front,
|
||||||
Back,
|
Back,
|
||||||
|
FrontAndBack,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,6 +32,10 @@ protected:
|
|||||||
std::vector<ShaderProgram> p_shaderPrograms;
|
std::vector<ShaderProgram> p_shaderPrograms;
|
||||||
std::vector<Texture> p_textures;
|
std::vector<Texture> p_textures;
|
||||||
|
|
||||||
|
Buffer* p_currentVertexBuffer;
|
||||||
|
Buffer* p_currentIndexBuffer;
|
||||||
|
ShaderProgram* p_currentShaderProgram;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
@ -64,14 +69,14 @@ public:
|
|||||||
virtual void createIndexBuffer(Buffer **buffer, int size, char* data) = 0;
|
virtual void createIndexBuffer(Buffer **buffer, int size, char* data) = 0;
|
||||||
virtual void useVertexBuffer(Buffer* buffer, int stride, int offset);
|
virtual void useVertexBuffer(Buffer* buffer, int stride, int offset);
|
||||||
virtual void useIndexBuffer(Buffer* buffer, int offset);
|
virtual void useIndexBuffer(Buffer* buffer, int offset);
|
||||||
virtual bool destroyBuffer(Buffer*& buffer);
|
virtual void destroyBuffer(Buffer*& buffer);
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
|
|
||||||
virtual void createVertexShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
virtual void createVertexShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
||||||
virtual void createFragmentShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
virtual void createFragmentShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
||||||
virtual void createGeometryShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
virtual void createGeometryShader(Shader** shader, const std::string& filename, const std::string& label) = 0;
|
||||||
virtual bool destroyShader(Shader*& shader);
|
virtual void destroyShader(Shader*& shader);
|
||||||
|
|
||||||
// Shader programs
|
// Shader programs
|
||||||
|
|
||||||
@ -84,7 +89,7 @@ public:
|
|||||||
// Textures
|
// Textures
|
||||||
|
|
||||||
virtual void createTexture(Texture** texture, const std::string& filename) = 0;
|
virtual void createTexture(Texture** texture, const std::string& filename) = 0;
|
||||||
virtual void useTexture(Texture* texture, int slot);
|
virtual void useTexture(Texture* texture, int slot) = 0;
|
||||||
virtual void destroyTexture(Texture*& texture);
|
virtual void destroyTexture(Texture*& texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
#include "buffer.hpp"
|
#include "buffer.hpp"
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
|
||||||
namespace hpr::gpu::opengl
|
namespace hpr::gpu::opengl
|
||||||
{
|
{
|
||||||
@ -14,14 +16,16 @@ Buffer::Buffer() :
|
|||||||
Buffer::~Buffer()
|
Buffer::~Buffer()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const int Buffer::target() const
|
int Buffer::target() const
|
||||||
{
|
{
|
||||||
switch (p_type)
|
switch (p_type)
|
||||||
{
|
{
|
||||||
case BufferType::Vertex:
|
case BufferType::Vertex:
|
||||||
return GL_ARRAY_BUFFER;
|
return GL_ARRAY_BUFFER;
|
||||||
case BufferType::Index:
|
case BufferType::Index:
|
||||||
return GL_ELEMENT_INDEX_BUFFER;
|
return GL_ELEMENT_ARRAY_BUFFER;
|
||||||
|
default:
|
||||||
|
return GL_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
|
||||||
const int target() const;
|
int target() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
|
|
||||||
#include "device.hpp"
|
#include "device.hpp"
|
||||||
#include "buffer.hpp
|
#include "buffer.hpp"
|
||||||
#include "shader.hpp"
|
#include "shader.hpp"
|
||||||
#include "shader_program.hpp"
|
#include "shader_program.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
|
||||||
|
#include "io/io.hpp"
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
namespace hpr::gpu::opengl
|
namespace hpr::gpu::opengl
|
||||||
{
|
{
|
||||||
@ -17,5 +22,187 @@ Device::Device() :
|
|||||||
Device::~Device()
|
Device::~Device()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
|
||||||
|
bool Device::initialize()
|
||||||
|
{
|
||||||
|
return p_isInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::destroy()
|
||||||
|
{
|
||||||
|
return p_isInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// State
|
||||||
|
|
||||||
|
void Device::faceCulling(bool enableFaceCulling, CullMode faceCullingMode)
|
||||||
|
{
|
||||||
|
if (enableFaceCulling)
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
else
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
switch (faceCullingMode)
|
||||||
|
{
|
||||||
|
case CullMode::Front:
|
||||||
|
glCullFace(GL_FRONT);
|
||||||
|
break;
|
||||||
|
case CullMode::Back:
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
break;
|
||||||
|
case CullMode::FrontAndBack:
|
||||||
|
glCullFace(GL_FRONT_AND_BACK);
|
||||||
|
break;
|
||||||
|
case CullMode::None:
|
||||||
|
glCullFace(GL_NONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::createVertexBuffer(gpu::Buffer **buffer, int size, char *data)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
throw std::invalid_argument("Invalid parameter");
|
||||||
|
|
||||||
|
*buffer = nullptr;
|
||||||
|
p_buffers.emplace_back(opengl::Buffer());
|
||||||
|
opengl::Buffer* newBuffer = dynamic_cast<opengl::Buffer*>(&p_buffers.back());
|
||||||
|
|
||||||
|
newBuffer->p_type = Buffer::BufferType::Vertex;
|
||||||
|
newBuffer->p_size = size;
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &newBuffer->p_vertexArrayIndex);
|
||||||
|
glBindVertexArray(newBuffer->p_vertexArrayIndex);
|
||||||
|
|
||||||
|
glGenBuffers(1, &newBuffer->p_bufferIndex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, newBuffer->p_bufferIndex);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, (void*)data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
*buffer = static_cast<gpu::Buffer*>(newBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::createIndexBuffer(gpu::Buffer **buffer, int size, char *data)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
throw std::invalid_argument("Invalid parameter");
|
||||||
|
|
||||||
|
*buffer = nullptr;
|
||||||
|
p_buffers.emplace_back(opengl::Buffer());
|
||||||
|
opengl::Buffer* newBuffer = dynamic_cast<opengl::Buffer*>(&p_buffers.back());
|
||||||
|
|
||||||
|
newBuffer->p_type = Buffer::BufferType::Vertex;
|
||||||
|
newBuffer->p_size = size;
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &newBuffer->p_vertexArrayIndex);
|
||||||
|
glBindVertexArray(newBuffer->p_vertexArrayIndex);
|
||||||
|
|
||||||
|
glGenBuffers(1, &newBuffer->p_bufferIndex);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, newBuffer->p_bufferIndex);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, size, (void*)data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
*buffer = static_cast<gpu::Buffer*>(newBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::useVertexBuffer(gpu::Buffer *buffer, int stride, int offset)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
{
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opengl::Buffer* curBuffer = dynamic_cast<opengl::Buffer*>(buffer);
|
||||||
|
|
||||||
|
if (curBuffer->p_type == Buffer::BufferType::Vertex && p_currentVertexBuffer != buffer)
|
||||||
|
{
|
||||||
|
glBindVertexArray(curBuffer->p_vertexArrayIndex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, curBuffer->p_bufferIndex);
|
||||||
|
|
||||||
|
opengl::Buffer* curIndexBuffer = dynamic_cast<opengl::Buffer*>(p_currentIndexBuffer);
|
||||||
|
|
||||||
|
if (curIndexBuffer != nullptr)
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, curIndexBuffer->p_bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpu::Device::useVertexBuffer(buffer, stride, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::useIndexBuffer(gpu::Buffer *buffer, int offset)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
{
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opengl::Buffer* curBuffer = dynamic_cast<opengl::Buffer*>(buffer);
|
||||||
|
|
||||||
|
if (curBuffer->p_type == Buffer::BufferType::Index && p_currentVertexBuffer != buffer)
|
||||||
|
{
|
||||||
|
glBindVertexArray(curBuffer->p_vertexArrayIndex);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, curBuffer->p_bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpu::Device::useIndexBuffer(buffer, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::destroyBuffer(gpu::Buffer *&buffer)
|
||||||
|
{
|
||||||
|
if (buffer == nullptr)
|
||||||
|
throw std::invalid_argument("Invalid parameter");
|
||||||
|
|
||||||
|
opengl::Buffer* curBuffer = dynamic_cast<opengl::Buffer*>(buffer);
|
||||||
|
glDeleteBuffers(1, &curBuffer->p_bufferIndex);
|
||||||
|
|
||||||
|
if (curBuffer->p_type == Buffer::BufferType::Vertex)
|
||||||
|
glDeleteVertexArrays(1, &curBuffer->p_vertexArrayIndex);
|
||||||
|
|
||||||
|
gpu::Device::destroyBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shaders
|
||||||
|
|
||||||
|
void Device::createVertexShader(gpu::Shader **shader, const std::string &filename, const std::string &label)
|
||||||
|
{
|
||||||
|
if (shader == nullptr)
|
||||||
|
throw std::invalid_argument("Invalid parameter");
|
||||||
|
|
||||||
|
*shader = nullptr;
|
||||||
|
|
||||||
|
unsigned int shaderIndex = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
if (shaderIndex == 0)
|
||||||
|
throw std::runtime_error("Could not create shader");
|
||||||
|
|
||||||
|
File file;
|
||||||
|
file.open(filename, File::Binary | File::Read);
|
||||||
|
std::string content = file.read().str();
|
||||||
|
const char* shaderSource = content.c_str();
|
||||||
|
|
||||||
|
glShaderSource(shaderIndex, 1, &shaderSource, nullptr);
|
||||||
|
GLenum result = glGetError();
|
||||||
|
glCompileShader(shaderIndex);
|
||||||
|
|
||||||
|
int shaderStatus;
|
||||||
|
glGetShaderiv(shaderIndex, GL_COMPILE_STATUS, &shaderStatus);
|
||||||
|
if (!shaderStatus)
|
||||||
|
{
|
||||||
|
char error[2048 + 1];
|
||||||
|
glGetShaderInfoLog(shaderIndex, 2048, nullptr, error);
|
||||||
|
|
||||||
|
throw std::runtime_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_shaders.emplace_back(opengl::Shader());
|
||||||
|
opengl::Shader* newShader = dynamic_cast<opengl::Shader*>(&p_shaders.back());
|
||||||
|
newShader->p_type = Shader::ShaderType::Vertex;
|
||||||
|
newShader->p_filename = filename;
|
||||||
|
newShader->p_shaderIndex = shaderIndex;
|
||||||
|
newShader->p_label = "VertexShader";
|
||||||
|
|
||||||
|
*shader = static_cast<Shader*>(newShader);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,6 +22,45 @@ public:
|
|||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
|
||||||
|
bool initialize() override;
|
||||||
|
bool destroy() override;
|
||||||
|
|
||||||
|
// State
|
||||||
|
|
||||||
|
void faceCulling(bool enableFaceCulling, CullMode faceCullingMode = CullMode::None) override;
|
||||||
|
|
||||||
|
// Buffers
|
||||||
|
|
||||||
|
void createVertexBuffer(Buffer **buffer, int size, char* data) override;
|
||||||
|
void createIndexBuffer(Buffer **buffer, int size, char* data) override;
|
||||||
|
void useVertexBuffer(Buffer* buffer, int stride, int offset) override;
|
||||||
|
void useIndexBuffer(Buffer* buffer, int offset) override;
|
||||||
|
void destroyBuffer(Buffer*& buffer) override;
|
||||||
|
|
||||||
|
// Shaders
|
||||||
|
|
||||||
|
void createVertexShader(Shader** shader, const std::string& filename, const std::string& label) override;
|
||||||
|
void createFragmentShader(Shader** shader, const std::string& filename, const std::string& label) override;
|
||||||
|
void createGeometryShader(Shader** shader, const std::string& filename, const std::string& label) override;
|
||||||
|
void destroyShader(Shader*& shader) override;
|
||||||
|
|
||||||
|
// Shader programs
|
||||||
|
|
||||||
|
virtual void createShaderProgram(ShaderProgram** program);
|
||||||
|
virtual void attachShader(ShaderProgram* program, Shader* shader);
|
||||||
|
virtual void linkProgram(ShaderProgram* program);
|
||||||
|
virtual void useShaderProgram(ShaderProgram* program);
|
||||||
|
virtual void destroyShaderProgram(ShaderProgram*& program, bool withShaders = false);
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
|
||||||
|
virtual void createTexture(Texture** texture, const std::string& filename);
|
||||||
|
virtual void useTexture(Texture* texture, int slot);
|
||||||
|
virtual void destroyTexture(Texture*& texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -7,17 +7,34 @@ namespace hpr::gpu
|
|||||||
|
|
||||||
Shader::Shader() :
|
Shader::Shader() :
|
||||||
Context {DeviceAPI::Unknown},
|
Context {DeviceAPI::Unknown},
|
||||||
p_filename {},
|
p_filename {"\0"},
|
||||||
p_label {}
|
p_label {"\0"},
|
||||||
|
p_type {ShaderType::Vertex}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Shader::Shader(DeviceAPI api) :
|
Shader::Shader(DeviceAPI api) :
|
||||||
Context {api},
|
Context {api},
|
||||||
p_filename {},
|
p_filename {"\0"},
|
||||||
p_label {}
|
p_label {"\0"},
|
||||||
|
p_type {ShaderType::Vertex}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
const std::string Shader::filename() const
|
||||||
|
{
|
||||||
|
return p_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string Shader::label() const
|
||||||
|
{
|
||||||
|
return p_label;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Shader::ShaderType Shader::type() const
|
||||||
|
{
|
||||||
|
return p_type;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -10,10 +10,7 @@ namespace hpr::gpu
|
|||||||
|
|
||||||
class Shader : public Context
|
class Shader : public Context
|
||||||
{
|
{
|
||||||
protected:
|
friend class Device;
|
||||||
|
|
||||||
std::string p_filename;
|
|
||||||
std::string p_label;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -25,6 +22,14 @@ public:
|
|||||||
ShaderTypeCount
|
ShaderTypeCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::string p_filename;
|
||||||
|
std::string p_label;
|
||||||
|
ShaderType p_type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
Shader();
|
Shader();
|
||||||
@ -39,7 +44,7 @@ public:
|
|||||||
|
|
||||||
const std::string label() const;
|
const std::string label() const;
|
||||||
|
|
||||||
const ShaderType shaderType() const;
|
const ShaderType type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace hpr::gpu
|
} // end namespace hpr::gpu
|
@ -11,6 +11,7 @@ namespace hpr::gpu
|
|||||||
|
|
||||||
class ShaderProgram : public Context
|
class ShaderProgram : public Context
|
||||||
{
|
{
|
||||||
|
friend class Device;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -23,4 +23,19 @@ Texture::Texture(DeviceAPI api) :
|
|||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
std::string Texture::filename() const
|
||||||
|
{
|
||||||
|
return p_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Texture::width() const
|
||||||
|
{
|
||||||
|
return p_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Texture::height() const
|
||||||
|
{
|
||||||
|
return p_height;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,11 @@ public:
|
|||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
|
||||||
const std::string filename() const();
|
std::string filename() const;
|
||||||
|
|
||||||
const int width() const;
|
int width() const;
|
||||||
|
|
||||||
const int height() const;
|
int height() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace hpr::gpu
|
} // end namespace hpr::gpu
|
@ -15,9 +15,12 @@ add_library(hyporo-hyplib STATIC
|
|||||||
vector/vector.hpp
|
vector/vector.hpp
|
||||||
matrix/MatrixSpace.hpp
|
matrix/MatrixSpace.hpp
|
||||||
matrix/matrix.hpp
|
matrix/matrix.hpp
|
||||||
|
io/file.hpp
|
||||||
|
io/io.hpp
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
scalar/scalar.cpp
|
scalar/scalar.cpp
|
||||||
|
io/file.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_GTESTS)
|
if(WITH_GTESTS)
|
||||||
|
70
source/hyporo/hyplib/io/file.cpp
Normal file
70
source/hyporo/hyplib/io/file.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
#include "file.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace hpr
|
||||||
|
{
|
||||||
|
|
||||||
|
File::File() :
|
||||||
|
p_name {"\0"},
|
||||||
|
p_mode {File::Read}
|
||||||
|
{}
|
||||||
|
|
||||||
|
File::File(const std::string &filename) :
|
||||||
|
p_name {filename},
|
||||||
|
p_mode {File::Read}
|
||||||
|
{}
|
||||||
|
|
||||||
|
File::File(const char *filename) :
|
||||||
|
p_name {filename},
|
||||||
|
p_mode {File::Read}
|
||||||
|
{}
|
||||||
|
|
||||||
|
File::~File()
|
||||||
|
{
|
||||||
|
if (p_file.is_open())
|
||||||
|
p_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::open(const std::string &filename, unsigned int filemode)
|
||||||
|
{
|
||||||
|
std::ios::openmode mode = filemode & File::Read ? std::ios::in : std::ios::out;
|
||||||
|
|
||||||
|
if (filemode & File::Binary)
|
||||||
|
mode |= std::ios::binary;
|
||||||
|
|
||||||
|
p_file.open(filename, mode);
|
||||||
|
|
||||||
|
if (!p_file.is_open())
|
||||||
|
throw std::ios::failure("Could not open file");
|
||||||
|
}
|
||||||
|
|
||||||
|
void File::close()
|
||||||
|
{
|
||||||
|
if (p_file.is_open())
|
||||||
|
p_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t File::length()
|
||||||
|
{
|
||||||
|
std::streampos size = 0;
|
||||||
|
std::streampos oldPos = p_file.tellg();
|
||||||
|
|
||||||
|
p_file.seekg(0, std::ios::beg);
|
||||||
|
size = p_file.tellg();
|
||||||
|
p_file.seekg(0, std::ios::end);
|
||||||
|
size = p_file.tellg() - size;
|
||||||
|
p_file.seekg(oldPos, std::ios::beg);
|
||||||
|
|
||||||
|
return (size_t)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream File::read()
|
||||||
|
{
|
||||||
|
std::stringstream content;
|
||||||
|
content << p_file.rdbuf();
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
53
source/hyporo/hyplib/io/file.hpp
Normal file
53
source/hyporo/hyplib/io/file.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace hpr
|
||||||
|
{
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum FileMode
|
||||||
|
{
|
||||||
|
Write = std::ios::out,
|
||||||
|
Read = std::ios::in,
|
||||||
|
Binary = std::ios::binary,
|
||||||
|
Append = std::ios::app
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::string p_name;
|
||||||
|
unsigned int p_mode;
|
||||||
|
std::fstream p_file;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
File();
|
||||||
|
|
||||||
|
File(const std::string& filename);
|
||||||
|
|
||||||
|
File(const char* filename);
|
||||||
|
|
||||||
|
~File();
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
void open(const std::string& filename, unsigned int filemode = File::Read);
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
size_t length();
|
||||||
|
|
||||||
|
std::stringstream read();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
4
source/hyporo/hyplib/io/io.hpp
Normal file
4
source/hyporo/hyplib/io/io.hpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "file.hpp"
|
||||||
|
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "scalar.hpp"
|
#include "scalar.hpp"
|
||||||
#include "VectorSpace.hpp"
|
#include "VectorSpace.hpp"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user