break stuff

This commit is contained in:
Bailey Harrison 2022-10-27 23:06:56 +01:00
parent d04e4a168a
commit d628414d69
11 changed files with 65 additions and 280 deletions

View File

@ -6,7 +6,6 @@ namespace engine {
class Window;
class Input;
class GFXDevice;
class ResourceManager;
class SceneRoot;

View File

@ -19,6 +19,8 @@ namespace engine {
GFXDevice& operator=(const GFXDevice&) = delete;
~GFXDevice();
void getViewportSize(uint32_t *w, uint32_t *h);
// adds a draw call to the queue
// vertexBuffer is required, indexBuffer can be NULL, uniformData is required
void draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData);

View File

@ -6,6 +6,8 @@
#include "transform.hpp"
#include "components/component.hpp"
#include <list>
#include <vector>
#include <string>
@ -141,4 +143,4 @@ namespace engine {
throw std::runtime_error("deleteComponent() error: attempt to delete component that is not present.");
}
}
}

View File

@ -9,6 +9,10 @@
#include <string>
#include <map>
namespace engine::gfx {
class Pipeline;
}
namespace engine::resources {
class ENGINE_API Shader : public Resource {
@ -17,58 +21,17 @@ public:
Shader(const std::filesystem::path& resPath);
~Shader() override;
enum class UniformType {
FLOAT_MAT4 = GL_FLOAT_MAT4,
FLOAT_VEC2 = GL_FLOAT_VEC2,
FLOAT_VEC3 = GL_FLOAT_VEC3,
SAMPLER_2D = GL_SAMPLER_2D,
NOTFOUND
struct UniformBuffer {
glm::mat4 transform;
};
void makeActive() const;
bool setUniform_m4(const std::string& name, const glm::mat4&) const;
bool setUniform_v2(const std::string& name, const glm::vec2&) const;
bool setUniform_v3(const std::string& name, const glm::vec3&) const;
bool setUniform_i(const std::string& name, int) const;
bool setUniform_f(const std::string& name, float) const;
UniformType getUniformType(const std::string& name) const;
int getAttribLocation(const std::string& name) const;
static void invalidate()
gfx::Pipeline* getPipeline()
{
s_activeProgram = std::numeric_limits<GLuint>::max();
return m_pipeline;
}
private:
struct Uniform {
GLint size;
UniformType type;
GLuint location;
};
struct Attribute {
GLint size;
UniformType type;
GLuint location;
};
// fields
GLuint m_program;
std::map<std::string, Uniform> m_uniforms{};
std::map<std::string, Attribute> m_attributes{};
// static members
// Only valid if glUseProgram is never called outside this class's method
static GLuint s_activeProgram;
// -1 if not found
int getUniformLocation(const std::string& name) const;
gfx::Pipeline* m_pipeline = nullptr;
};

View File

@ -7,11 +7,9 @@
#include "window.hpp"
#include "log.hpp"
#include "gfx_device.hpp"
static const std::string VIEW_MAT_UNIFORM = "viewMat";
static const std::string PROJ_MAT_UNIFORM = "projMat";
static const std::string WINDOW_SIZE_UNIFORM = "windowSize";
#include "log.hpp"
namespace engine::components {
@ -20,11 +18,6 @@ glm::vec4 Camera::s_clearColor{-999.0f, -999.0f, -999.0f, -999.0f};
Camera::Camera(Object* parent) : Component(parent, TypeEnum::CAMERA)
{
parent->root.activateCam(getID());
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_CULL_FACE);
}
Camera::~Camera()
@ -52,26 +45,17 @@ void Camera::updateCam(glm::mat4 transform)
// shader ref count increased by 1, but only in this scope
auto lockedPtr = resPtr.lock();
auto shader = dynamic_cast<Shader*>(lockedPtr.get());
shader->setUniform_m4(VIEW_MAT_UNIFORM, viewMatrix);
shader->setUniform_m4(PROJ_MAT_UNIFORM, m_projMatrix);
// shader->setUniform_v2(WINDOW_SIZE_UNIFORM, win.getViewportSize());
shader->setUniform_v3("lightPos", m_lightPos);
// SET VIEW TRANSFORM HERE
}
if (s_clearColor != clearColor) {
s_clearColor = clearColor;
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
}
glClear((m_noClear ? 0 : GL_COLOR_BUFFER_BIT) | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
static glm::vec2 getViewportSize()
{
GLint64 viewportParams[4];
glGetInteger64v(GL_VIEWPORT, viewportParams);
return { viewportParams[2], viewportParams[3] };
uint32_t width;
uint32_t height;
gfxdev->getViewportSize(&width, &height);
return {width, height};
}
void Camera::usePerspective(float fovDeg)

View File

@ -4,14 +4,16 @@
#include "resource_manager.hpp"
#include "gfx_device.hpp"
#include <iostream>
namespace engine::components {
Renderer::Renderer(Object* parent) : Component(parent, TypeEnum::RENDERER)
{
m_shader = this->parent.res.get<resources::Shader>("shaders/basic.glsl");
m_texture = this->parent.res.get<resources::Texture>("textures/missing.png");
m_shader = this->parent.res.get<resources::Shader>("shader.glsl");
// m_texture = this->parent.res.get<resources::Texture>("textures/missing.png");
}
Renderer::~Renderer()
@ -21,30 +23,21 @@ Renderer::~Renderer()
void Renderer::render(glm::mat4 transform)
{
resources::Shader::UniformBuffer ub {
glm::mat4{1.0f},
};
m_shader->setUniform_f("ambientStrength", 0.4f);
m_shader->setUniform_v3("ambientColor", { 1.0f, 1.0f, 1.0f });
m_shader->setUniform_v3("lightColor", { 1.0f, 1.0f, 1.0f });
m_shader->setUniform_m4("modelMat", transform );
m_texture->bindTexture();
m_shader->setUniform_v3("baseColor", m_color );
m_shader->setUniform_v3("emission", m_emission );
// if (m_mesh)
// m_mesh->drawMesh(*m_shader);
gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_indices.size(), &ub);
}
void Renderer::setMesh(const std::string& name)
{
// m_mesh = parent.res.get<resources::Mesh>(name);
m_mesh = parent.res.get<resources::Mesh>(name);
}
void Renderer::setTexture(const std::string& name)
{
m_texture = parent.res.get<resources::Texture>(name);
// m_texture = parent.res.get<resources::Texture>(name);
}
}

View File

@ -23,12 +23,15 @@ UI::~UI()
void UI::render(glm::mat4 transform)
{
/*
glActiveTexture(GL_TEXTURE0);
m_shader->setUniform_m4("modelMat", transform);
m_shader->setUniform_v3("textColor", m_color);
m_shader->setUniform_i("textScaling", (int)m_scaled);
*/
std::vector<resources::Font::Character> glyphs;
for (char c : m_text) {
glyphs.push_back(m_font->getChar(c));

View File

@ -11,11 +11,8 @@
#include "resources/mesh.hpp"
struct UBO {
glm::mat4 model{};
glm::mat4 view{};
glm::mat4 proj{};
};
#include "components/mesh_renderer.hpp"
#include "components/camera.hpp"
static engine::gfx::Pipeline* pipeline;
static engine::gfx::Buffer* vb;
@ -28,7 +25,6 @@ namespace engine {
m_win = std::make_unique<Window>(appName, true);
gfxdev = new GFXDevice(appName, appVersion, m_win->getHandle());
m_input = std::make_unique<Input>(*m_win);
m_res = std::make_unique<ResourceManager>();
GameIO things{};
@ -36,6 +32,9 @@ namespace engine {
things.input = m_input.get();
things.resMan = m_res.get();
m_scene = std::make_unique<SceneRoot>(things);
m_scene->createChild("player")->createComponent<components::Renderer>()->setMesh("meshes/cube.mesh");
m_scene->createChild("cam")->createComponent<components::Camera>();
}
Application::~Application()
@ -50,8 +49,6 @@ namespace engine {
uint64_t lastTick = m_win->getNanos();
constexpr int TICKFREQ = 1; // in hz
auto myMesh = m_res->get<resources::Mesh>("meshes/monke.mesh");
// single-threaded game loop
while (m_win->isRunning()) {

View File

@ -1083,6 +1083,12 @@ namespace engine {
vkDestroyInstance(pimpl->instance, nullptr);
}
void GFXDevice::getViewportSize(uint32_t *w, uint32_t *h)
{
*w = pimpl->swapchain.extent.width;
*h = pimpl->swapchain.extent.height;
}
void GFXDevice::draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData)
{
assert(vertexBuffer->type == gfx::BufferType::VERTEX);
@ -1101,6 +1107,7 @@ namespace engine {
memcpy(call.uniformData, uniformData, uniformDataSize);
pimpl->drawQueues[pipeline].push(call);
}
void GFXDevice::renderFrame()
@ -1171,6 +1178,7 @@ namespace engine {
vkCmdBindPipeline(pimpl->commandBuffers[frameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
vkCmdBindDescriptorSets(pimpl->commandBuffers[frameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, 0, 1, &pipeline->descriptorSets[frameIndex], 0, nullptr);
while (queue.empty() == false) {
DrawCall call = queue.front();
void* uniformDest;

View File

@ -2,6 +2,8 @@
#include "gfx_device.hpp"
#include "log.hpp"
namespace engine::resources {
struct MeshFileHeader {
@ -38,6 +40,12 @@ void Mesh::initMesh()
{
vb = gfxdev->createBuffer(gfx::BufferType::VERTEX, m_vertices.size() * sizeof(Vertex), m_vertices.data());
ib = gfxdev->createBuffer(gfx::BufferType::INDEX, m_indices.size() * sizeof(uint32_t), m_indices.data());
TRACE("Vertices:");
for (const auto& v : m_vertices) {
TRACE("pos: {}, {}, {}", v.pos.x, v.pos.y, v.pos.z);
}
}
Mesh::Mesh(const std::vector<Vertex>& vertices) : Resource("", "mesh")

View File

@ -1,8 +1,8 @@
#include "resources/shader.hpp"
#include <glad/glad.h>
#include "log.hpp"
#include <log.hpp>
#include "gfx_device.hpp"
#include <string>
#include <fstream>
@ -24,200 +24,26 @@ static std::unique_ptr<std::vector<char>> readFile(const char * path)
return buf;
}
static GLuint compile(const char *path, GLenum type)
{
auto src = readFile(path);
// compile shader
GLuint handle = glCreateShader(type);
GLint size = (GLint)src->size();
GLchar *data = src->data();
glShaderSource(handle, 1, &data, &size);
glCompileShader(handle);
// check for compilation error
GLint compiled;
glGetShaderiv(handle, GL_COMPILE_STATUS, &compiled);
if (compiled == 0) {
GLint log_len;
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_len);
GLchar *log_msg = (GLchar *)calloc(1, log_len);
if (log_msg == NULL) {
throw std::runtime_error("Error allocating memory for shader compilation error log");
}
glGetShaderInfoLog(handle, log_len, NULL, log_msg);
throw std::runtime_error("Shader compilation error in " + std::string(path) + " log:\n" + std::string(log_msg));
} return handle;
}
namespace engine::resources {
// I've got to do this because of GL's stupid state machine
GLuint Shader::s_activeProgram = 0;
Shader::Shader(const std::filesystem::path& resPath) : Resource(resPath, "shader")
{
const std::string vertexShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".vert")).string();
const std::string fragmentShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".frag")).string();
GLuint vs = compile(vertexShaderPath.c_str(), GL_VERTEX_SHADER);
GLuint fs = compile(fragmentShaderPath.c_str(), GL_FRAGMENT_SHADER);
m_program = glCreateProgram();
glAttachShader(m_program, vs);
glAttachShader(m_program, fs);
glLinkProgram(m_program);
glValidateProgram(m_program);
gfx::VertexFormat vertexFormat {};
vertexFormat.attributeDescriptions.emplace_back(0, gfx::VertexAttribFormat::VEC3, 0); // pos
vertexFormat.attributeDescriptions.emplace_back(1, gfx::VertexAttribFormat::VEC3, sizeof(glm::vec3)); // norm
vertexFormat.attributeDescriptions.emplace_back(2, gfx::VertexAttribFormat::VEC2, sizeof(glm::vec3) + sizeof(glm::vec3)); // uv
// flag shader objects for deletion, this does not take effect until the program is deleted
glDeleteShader(vs);
glDeleteShader(fs);
const std::string vertexShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".vert.spv")).string();
const std::string fragmentShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".frag.spv")).string();
GLint linked, validated;
glGetProgramiv(m_program, GL_LINK_STATUS, &linked);
glGetProgramiv(m_program, GL_VALIDATE_STATUS, &validated);
if (linked == 0 || validated == 0) {
GLint log_len;
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &log_len);
GLchar *log_msg = (GLchar *)calloc(1, log_len);
if (log_msg == NULL) {
throw std::runtime_error("Error allocating memory for shader linking error log");
}
glGetProgramInfoLog(m_program, log_len, NULL, log_msg);
throw std::runtime_error("Program linking error with " + vertexShaderPath + " and " + fragmentShaderPath + " log:\n" + log_msg);
}
DEBUG("For shader {}:", resPath.filename().string());
// now get uniforms
GLint count;
glGetProgramiv(m_program, GL_ACTIVE_UNIFORMS, &count);
for (int i = 0; i < count; i++) {
char nameBuf[64] = {};
GLint size;
GLenum type;
glGetActiveUniform(m_program, i, 63, NULL, &size, &type, nameBuf);
m_uniforms[nameBuf] = Uniform{size, static_cast<UniformType>(type), (GLuint)i};
DEBUG("\tuniform {}", nameBuf);
}
// now get all attributes
glGetProgramiv(m_program, GL_ACTIVE_ATTRIBUTES, &count);
for (int i = 0; i < count; i++) {
char nameBuf[64] = {};
GLint size;
GLenum type;
glGetActiveAttrib(m_program, i, 63, NULL, &size, &type, nameBuf);
m_attributes[nameBuf] = Attribute{size, static_cast<UniformType>(type), (GLuint)i};
DEBUG("\tattrib {}", nameBuf);
}
m_pipeline = gfxdev->createPipeline(vertexShaderPath.c_str(), fragmentShaderPath.c_str(), vertexFormat, sizeof(UniformBuffer));
}
Shader::~Shader()
{
glDeleteProgram(m_program);
}
void Shader::makeActive() const
{
if (s_activeProgram != m_program) {
glUseProgram(m_program);
s_activeProgram = m_program;
}
}
int Shader::getUniformLocation(const std::string& name) const
{
auto it = m_uniforms.find(name);
if (it != m_uniforms.end()) {
Uniform u = it->second;
return u.location;
}
else {
return -1;
}
}
bool Shader::setUniform_m4(const std::string& name, const glm::mat4& m) const
{
makeActive();
int loc = getUniformLocation(name);
if (loc != -1) {
glUniformMatrix4fv(loc, 1, GL_FALSE, &m[0][0]);
return true;
}
else {
return false;
}
}
bool Shader::setUniform_v2(const std::string& name, const glm::vec2& v) const
{
makeActive();
int loc = getUniformLocation(name);
if (loc != -1) {
glUniform2f(loc, v.x, v.y);
return true;
}
else {
return false;
}
}
bool Shader::setUniform_v3(const std::string& name, const glm::vec3& v) const
{
makeActive();
int loc = getUniformLocation(name);
if (loc != -1) {
glUniform3f(loc, v.x, v.y, v.z);
return true;
}
else {
return false;
}
}
bool Shader::setUniform_i(const std::string& name, int n) const
{
makeActive();
int loc = getUniformLocation(name);
if (loc != -1) {
glUniform1i(loc, n);
return true;
}
else {
return false;
}
}
bool Shader::setUniform_f(const std::string& name, float n) const
{
makeActive();
int loc = getUniformLocation(name);
if (loc != -1) {
glUniform1f(loc, n);
return true;
}
else {
return false;
}
}
Shader::UniformType Shader::getUniformType(const std::string& name) const
{
auto it = m_uniforms.find(name);
if (it != m_uniforms.end()) {
return it->second.type;
}
else {
return UniformType::NOTFOUND;
}
}
int Shader::getAttribLocation(const std::string& name) const
{
return m_attributes.at(name).location;
gfxdev->destroyPipeline(m_pipeline);
}
}