Add stuff

This commit is contained in:
bailwillharr 2022-11-27 14:35:41 +00:00
parent e495183019
commit 69dae9ab42
18 changed files with 137 additions and 284 deletions

View File

@ -1,7 +1,5 @@
#pragma once
#if 0
#include "engine_api.h"
#include "component.hpp"
@ -14,17 +12,17 @@
namespace engine::components {
class ENGINE_API UI : public Component {
class ENGINE_API UI : public Component {
public:
public:
UI(Object*);
~UI() override;
// called every frame, do not call manually
void render(glm::mat4 transform);
void render(glm::mat4 transform, glm::mat4 view);
std::string m_text = "hello world";
glm::vec3 m_color = {1.0f, 1.0f, 1.0f};
glm::vec3 m_color = { 1.0f, 1.0f, 1.0f };
enum class Alignment {
NONE = 0,
@ -34,11 +32,12 @@ public:
Alignment m_alignment = Alignment::LEFT;
bool m_scaled = true;
private:
private:
std::shared_ptr<resources::Font> m_font;
std::shared_ptr<resources::Shader> m_shader;
};
std::unique_ptr<resources::Mesh> m_atlasMesh;
};
}
#endif

View File

@ -29,7 +29,7 @@ namespace engine {
void renderFrame();
// creates the equivalent of an OpenGL shader program & vertex attrib configuration
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize);
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling);
void destroyPipeline(const gfx::Pipeline* pipeline);
void updateUniformBuffer(const gfx::Pipeline* pipeline, void* data, size_t size, uint32_t offset);

View File

@ -16,19 +16,13 @@ class ENGINE_API Font : public Resource {
public:
struct Character {
gfx::Texture* texture;
glm::ivec2 size;
glm::ivec2 bearing; // offset from baseline to top-left of glyph
long advance; // offset to the next glyph
};
Font(const std::filesystem::path& resPath);
~Font() override;
Character getChar(char c);
private:
std::map<char, Character> m_characters;
const gfx::Texture* getAtlasTexture();
private:
const gfx::Texture* m_atlas;
};

View File

@ -16,7 +16,7 @@ namespace engine::components {
Renderer::Renderer(Object* parent) : Component(parent, TypeEnum::RENDERER)
{
m_shader = this->parent.res.get<resources::Shader>("shader.glsl");
m_shader = this->parent.res.get<resources::Shader>("shaders/texture.glsl");
m_texture = this->parent.res.get<resources::Texture>("textures/white.png");
}

View File

@ -1,5 +1,3 @@
#if 0
#include "components/text_ui_renderer.hpp"
#include "object.hpp"
@ -14,76 +12,35 @@ UI::UI(Object* parent) : Component(parent, TypeEnum::UI)
m_font = parent->res.get<resources::Font>(FONTFILE);
m_shader = parent->res.get<resources::Shader>("shaders/font.glsl");
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
m_atlasMesh = std::make_unique<resources::Mesh>(std::vector<Vertex>{
{ { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } },
{ { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f } },
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f } },
{ { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } },
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f } },
{ { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f } }
});
}
UI::~UI()
{
}
void UI::render(glm::mat4 transform)
void UI::render(glm::mat4 transform, glm::mat4 view)
{
/*
glActiveTexture(GL_TEXTURE0);
m_shader->setUniform_m4("modelMat", transform);
struct {
glm::mat4 m;
glm::vec2 offset;
glm::vec2 size;
} pushConsts{};
m_shader->setUniform_v3("textColor", m_color);
m_shader->setUniform_i("textScaling", (int)m_scaled);
pushConsts.m = glm::mat4{1.0f};
*/
std::vector<resources::Font::Character> glyphs;
for (char c : m_text) {
glyphs.push_back(m_font->getChar(c));
}
constexpr float scale = 0.002f;
float x = 0.0f;
if (m_alignment == Alignment::RIGHT) {
// first find the length of the text
float len = 0.0f;
for (const auto& glyph : glyphs) {
len += (glyph.advance >> 6) * scale;
}
x = -len;
}
for (const auto& glyph : glyphs) {
float xpos = x + glyph.bearing.x * scale;
float ypos = (glyph.bearing.y - glyph.size.y) * scale;
float w = glyph.size.x * scale;
float h = glyph.size.y * scale;
/*
resources::Mesh mesh({
{{xpos, ypos + h, 0.0f}, {}, {0.0f, 0.0f}},
{{xpos, ypos , 0.0f}, {}, {0.0f, 1.0f}},
{{xpos + w, ypos, 0.0f}, {}, {1.0f, 1.0f}},
{{xpos, ypos + h, 0.0f}, {}, {0.0f, 0.0f}},
{{xpos + w, ypos, 0.0f}, {}, {1.0f, 1.0f}},
{{xpos + w, ypos + h, 0.0f}, {}, {1.0f, 0.0f}},
});*/
// glBindTexture(GL_TEXTURE_2D, glyph.textureID);
// mesh.drawMesh(*m_shader);
x += (glyph.advance >> 6) * scale;
}
resources::Texture::invalidate();
gfxdev->draw(m_shader->getPipeline(), m_atlasMesh->vb, m_atlasMesh->ib, m_atlasMesh->m_indices.size(), &pushConsts, sizeof(pushConsts), m_font->getAtlasTexture());
}
}
#endif

View File

@ -1570,7 +1570,7 @@ namespace engine {
renderPassInfo.renderArea.extent = pimpl->swapchain.extent;
std::array<VkClearValue, 2> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };
clearValues[0].color = { {0.1f, 0.1f, 0.8f, 1.0f} };
clearValues[1].depthStencil = { 1.0f, 0 };
renderPassInfo.clearValueCount = (uint32_t)clearValues.size();
renderPassInfo.pClearValues = clearValues.data();
@ -1666,7 +1666,7 @@ namespace engine {
pimpl->FRAMECOUNT++;
}
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize)
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling)
{
VkResult res;
@ -1826,7 +1826,12 @@ namespace engine {
rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f;
if (backfaceCulling == true) {
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
}
else {
rasterizer.cullMode = VK_CULL_MODE_NONE;
}
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;
rasterizer.depthBiasConstantFactor = 0.0f; // ignored
@ -1848,13 +1853,18 @@ namespace engine {
VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT;
if (alphaBlending) {
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
}
else {
colorBlendAttachment.blendEnable = VK_FALSE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // ignored
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // ignored
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // ignored
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // ignored
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // ignored
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // ignored
}
VkPipelineColorBlendStateCreateInfo colorBlending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;

View File

@ -123,8 +123,7 @@ namespace engine {
compList.renderers.emplace_back(dynamic_cast<Renderer*>(comp), newTransform);
break;
case Component::TypeEnum::UI:
// compList.uis.emplace_back(dynamic_cast<UI*>(comp), newTransform);
throw std::runtime_error("UI is currently not supported");
compList.uis.emplace_back(dynamic_cast<UI*>(comp), newTransform);
break;
case Component::TypeEnum::CUSTOM:
compList.customs.emplace_back(dynamic_cast<CustomComponent*>(comp), newTransform);

View File

@ -14,63 +14,36 @@ Font::Font(const std::filesystem::path& resPath) : Resource(resPath, "font")
{
// TODO: load font
auto fontBuffer = util::readBinaryFile(resPath);
auto fontBuffer = util::readBinaryFile(resPath.string());
stbtt_fontinfo info{};
int res = stbtt_InitFont(&info, fontBuffer->data(), 0);
if (!res) {
throw std::runtime_error("Failed to read font file: " + resPath.string());
constexpr int BITMAP_WIDTH = 1024;
constexpr int BITMAP_HEIGHT = 1024;
auto pixels = std::make_unique<unsigned char[]>(BITMAP_WIDTH * BITMAP_HEIGHT);
auto chardata = std::make_unique<stbtt_bakedchar[]>(96);
stbtt_BakeFontBitmap(fontBuffer->data(), 0, 128.0f, pixels.get(), BITMAP_WIDTH, BITMAP_HEIGHT, 32, 96, chardata.get());
auto textureData = std::make_unique<uint8_t[]>(BITMAP_WIDTH * BITMAP_HEIGHT * 4);
for (int i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++) {
textureData[i * 4 + 0] = pixels[i];
textureData[i * 4 + 1] = pixels[i];
textureData[i * 4 + 2] = pixels[i];
textureData[i * 4 + 3] = pixels[i];
}
float scale = stbtt_ScaleForPixelHeight(&info, 64);
for (unsigned char c = 0; c < 128; c++) {
// TODO: get character bitmap buffer, size, offsets, advance
int32_t advance = 0, xoff = 0;
stbtt_GetCodepointHMetrics(&info, c, &advance, &xoff);
int32_t w, h, yoff;
const uint8_t* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, c, &w, &h, &xoff, &yoff);
DEBUG("char width: {} char height: {}", w, h);
auto colorBuffer = std::make_unique<std::vector<uint32_t>>(w * h);
int i = 0;
for (uint32_t& col : *colorBuffer) {
if (bitmap[i] == 0) {
col = 0;
} else {
col = 0xFFFFFFFF;
}
i++;
}
// generate texture
gfx::Texture* texture = gfxdev->createTexture(colorBuffer->data(), w, h, gfx::TextureFilter::LINEAR, gfx::TextureFilter::LINEAR);
Character character = {
texture,
glm::ivec2{w, h}, // Size of Glyph
glm::ivec2{xoff, yoff}, // Offset from baseline (bottom-left) to top-left of glyph
advance
};
m_characters.insert(std::make_pair(c, character));
}
// TODO clean up resources
m_atlas = gfxdev->createTexture(textureData.get(), BITMAP_WIDTH, BITMAP_HEIGHT, gfx::TextureFilter::LINEAR, gfx::TextureFilter::LINEAR);
}
Font::~Font()
{
gfxdev->destroyTexture(m_atlas);
}
Font::Character Font::getChar(char c)
const gfx::Texture* Font::getAtlasTexture()
{
return m_characters.at(c);
return m_atlas;
}
}

View File

@ -4,25 +4,7 @@
#include "gfx_device.hpp"
#include <string>
#include <fstream>
#include <vector>
#include <span>
static std::unique_ptr<std::vector<char>> readFile(const char * path)
{
std::ifstream file(path, std::ios::binary | std::ios::ate);
//file.exceptions(std::ifstream::failbit); // throw exception if file cannot be opened
if (file.fail()) {
throw std::runtime_error("Failed to open file for reading: " + std::string(path));
}
size_t size = file.tellg();
file.seekg(0, std::ios::beg);
auto buf = std::make_unique<std::vector<char>>();
buf->resize(size);
file.rdbuf()->sgetn(buf->data(), size);
return buf;
}
namespace engine::resources {
@ -38,7 +20,7 @@ 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();
m_pipeline = gfxdev->createPipeline(vertexShaderPath.c_str(), fragmentShaderPath.c_str(), vertexFormat, sizeof(UniformBuffer));
m_pipeline = gfxdev->createPipeline(vertexShaderPath.c_str(), fragmentShaderPath.c_str(), vertexFormat, sizeof(UniformBuffer), true, true);
}

View File

@ -57,16 +57,16 @@ namespace engine {
ren->render(ren_t, view);
}
for (const auto& [textRen, textRen_t] : compList.uis) {
textRen->render(textRen_t, view);
}
break;
}
}
}
/* for (const auto& [c, t] : compList.uis) {
c->render(t);
}
*/
}
void SceneRoot::activateCam(int id)

BIN
test/res/models/van/van.dae (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,37 +0,0 @@
#version 330
uniform float ambientStrength;
uniform vec3 ambientColor;
uniform vec3 lightColor;
uniform vec3 emission;
uniform vec3 baseColor;
uniform sampler2D tex;
in vec3 f_Pos;
in vec3 f_Norm;
in vec2 f_UV;
in vec3 f_lightPos;
out vec4 FragColor;
void main() {
vec3 norm = normalize(f_Norm);
vec3 lightDir = normalize(f_lightPos - f_Pos);
vec3 diffuse = max(dot(norm, lightDir), 0.0) * lightColor;
vec3 ambient = ambientColor * ambientStrength;
vec3 viewDir = normalize(-f_Pos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = 0.5 * spec * lightColor;
vec3 lighting = min(diffuse + ambient + specular, 1.0);
FragColor = min( ( vec4(baseColor, 1.0) * texture(tex, f_UV) ) * vec4(lighting + emission, 1.0), vec4(1.0));
}

View File

@ -1,26 +0,0 @@
#version 330
layout (location = 0) in vec3 v_Position;
layout (location = 1) in vec3 v_Norm;
layout (location = 2) in vec2 v_UV;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
uniform vec3 lightPos;
out vec3 f_Pos;
out vec3 f_Norm;
out vec2 f_UV;
out vec3 f_lightPos;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(v_Position, 1.0);
f_Pos = vec3(viewMat * modelMat * vec4(v_Position, 1.0));
f_Norm = mat3(transpose(inverse(viewMat * modelMat))) * v_Norm;
f_UV = v_UV;
f_lightPos = vec3(viewMat * vec4(lightPos, 1.0));
}

View File

@ -1,14 +1,12 @@
#version 330
#version 450
uniform vec3 textColor;
layout(location = 0) in vec2 fragUV;
uniform sampler2D tex;
layout(location = 0) out vec4 outColor;
in vec2 f_UV;
layout(set = 1, binding = 0) uniform sampler2D texSampler;
out vec4 FragColor;
void main()
{
FragColor = vec4(textColor, texture(tex, f_UV).r);
void main() {
outColor = texture(texSampler, fragUV);
}

View File

@ -1,25 +1,18 @@
#version 330
#version 450
uniform vec2 windowSize;
uniform bool textScaling; // true means keep text aspect ratio
layout( push_constant ) uniform Constants {
mat4 model;
vec2 offset;
vec2 size;
} constants;
layout (location = 0) in vec3 v_Position;
layout (location = 2) in vec2 v_UV;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inNorm;
layout(location = 2) in vec2 inUV;
uniform mat4 modelMat;
layout(location = 0) out vec2 fragUV;
out vec2 f_UV;
void main()
{
float aspect = windowSize.y / windowSize.x;
vec3 pos = v_Position;
if (textScaling) {
pos.x *= aspect;
}
gl_Position = modelMat * vec4(pos, 1.0);
f_UV = v_UV;
void main() {
gl_Position = constants.model * vec4(inPosition, 1.0);
fragUV = inUV;
}

View File

@ -14,7 +14,7 @@ void main() {
// constants
vec3 lightColor = vec3(1.0, 1.0, 1.0);
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
float ambientStrength = 0.1;
float ambientStrength = 0.05;
vec3 baseColor = vec3(texture(texSampler, fragUV));
vec3 emission = vec3(0.0, 0.0, 0.0);

View File

@ -23,6 +23,6 @@ void main() {
fragPos = vec3(constants.view * constants.model * vec4(inPosition, 1.0));
fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm;
fragUV = inUV;
vec3 lightPos = vec3(-5.0, 20.0, 5.0);
vec3 lightPos = vec3(-500.0, 500.0, 40.0);
fragLightPos = vec3(constants.view * vec4(lightPos, 1.0));
}

View File

@ -8,6 +8,7 @@
#include "components/camera.hpp"
#include "components/mesh_renderer.hpp"
#include "components/text_ui_renderer.hpp"
#include "resource_manager.hpp"
#include "resources/texture.hpp"
@ -73,6 +74,7 @@ void playGame()
// FLOOR
/*
constexpr float GRASS_DENSITY = 128.0f * 20.0f;
auto floor = app.scene()->createChild("floor");
auto floorRenderer = floor->createComponent<engine::components::Renderer>();
@ -87,11 +89,12 @@ void playGame()
{ { -16.0f, 0.0f, 16.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, GRASS_DENSITY } }
});
floor->transform.scale = { 100.0f, 1.0f, 100.0f };
*/
/*
auto cube = app.scene()->createChild("cube");
auto cubeRen = cube->createComponent<engine::components::Renderer>();
cubeRen->setMesh("meshes/cube.mesh");
cube->transform.position = glm::vec3{ -5.0f, 1.0f, 0.0f };
class Spin : public engine::components::CustomComponent {
@ -126,12 +129,13 @@ void playGame()
};
app.scene()->getChild("cube")->createComponent<Spin>();
*/
auto sphere = app.scene()->createChild("sphere");
/*auto sphere = app.scene()->createChild("sphere");
sphere->transform.position = { 10.0f, 5.0f, 10.0f };
*/
auto sphereRenderer = sphere->createComponent<engine::components::Renderer>();
/*auto sphereRenderer = sphere->createComponent<engine::components::Renderer>();
sphereRenderer->m_mesh = genSphereMesh(5.0f, 100, false);
sphereRenderer->setTexture("textures/cobble_stone.png");
@ -140,7 +144,13 @@ void playGame()
auto boundsRen = bounds->createComponent<engine::components::Renderer>();
boundsRen->m_mesh = genSphereMesh(100.0f, 36, true);
boundsRen->setTexture("textures/metal.jpg");
*/
auto message = app.scene()->createChild("message");
message->transform.position = { 0.0f, 2.0f, 0.0f };
auto messageUI = message->createComponent<engine::components::UI>();
/*
auto myModel = engine::util::loadAssimpMeshFromFile(app.scene(), app.resources()->getFilePath("models/pyramid/pyramid.dae").string());
myModel->transform.position = { -5.0f, 2.0f, 7.0f };
@ -153,14 +163,12 @@ void playGame()
auto plane = engine::util::loadAssimpMeshFromFile(app.scene(), app.resources()->getFilePath("models/plane/plane.dae").string());
plane->transform.position = { -30.0f, 2.0f, 10.0f };
*/
auto lego = engine::util::loadAssimpMeshFromFile(app.scene(), app.resources()->getFilePath("models/lego/lego.dae").string());
lego->transform.position = { 30.0f, -2.0f, 30.0f };
lego->transform.scale = { 0.1f, 0.1f, 0.1f };
lego->transform.position = { -30.0f, -33.0f, -30.0f };
app.scene()->printTree();
auto myFont = app.resources()->get<engine::resources::Font>("fonts/LiberationMono-Regular.ttf");
app.gameLoop();
}