Port from tinygltf to fx-gltf

This commit is contained in:
2022-10-14 23:55:55 +02:00
parent 5bdeae8dad
commit 7a53bac2c9
25 changed files with 8189 additions and 546 deletions

View File

@@ -6,6 +6,8 @@ AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakTemplateDeclarations: 'true'
BreakBeforeBraces: Mozilla
BinPackParameters: 'false'
BinPackArguments: 'false'
ColumnLimit: '120'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
IndentWidth: '4'

3
.gitmodules vendored
View File

@@ -13,3 +13,6 @@
[submodule "lib/glfw"]
path = lib/glfw
url = https://github.com/glfw/glfw.git
[submodule "lib/fx-gltf"]
path = lib/fx-gltf
url = https://github.com/jessey-git/fx-gltf.git

View File

@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.20)
cmake_policy(SET CMP0135 NEW)
project(
Fall-Fever
@@ -9,6 +10,11 @@ project(
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(FetchContent)
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz)
FetchContent_MakeAvailable(json)
find_package(glm REQUIRED)
find_package(spdlog REQUIRED)

View File

@@ -40,7 +40,7 @@
"name": "flags-unix",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wshadow -Wformat=2 -Wundef -Werror=float-equal"
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wshadow -Wformat=2 -Wundef"
}
},
{

View File

@@ -4,12 +4,12 @@ layout(location = 0) out vec4 f_color;
in vec3 v_normal;
in vec2 v_texCoord;
in vec3 v_fragmentPositionTangent;
in vec3 v_fragmentPosition;
in vec3 v_lightDirectionTangent;
in vec3 v_lightPositionTangent0;
in vec3 v_lightDirection;
in vec3 v_lightPosition0;
in vec3 v_viewPositionTangent;
in vec3 v_viewPosition;
struct Material
{
@@ -61,12 +61,12 @@ void main()
vec3 normal = texture(u_material.texture_normal, v_texCoord).rgb;
normal = normalize(normal * 2.0 - 1.0);
vec3 viewDir = normalize(v_viewPositionTangent - v_fragmentPositionTangent);
vec3 viewDir = normalize(v_viewPosition - v_fragmentPosition);
fragmentColor += directionalLightContribution(u_directionalLight, normal, viewDir);
for (int i = 0; i < NUM_POINT_LIGHTS; i++) {
fragmentColor += pointLightContribution(u_pointLight[i], normal, v_fragmentPositionTangent, viewDir);
fragmentColor += pointLightContribution(u_pointLight[i], normal, v_fragmentPosition, viewDir);
}
f_color = vec4(fragmentColor, 1.0f);
@@ -78,7 +78,7 @@ vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 view
if (!light.isActive)
return vec3(0.0f);
vec3 lightDir = normalize(-v_lightDirectionTangent);
vec3 lightDir = normalize(-v_lightDirection);
vec3 diffuseColor = light.color;
vec3 specularColor = light.color * 0.5f;
@@ -96,7 +96,7 @@ vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 vi
if (!light.isActive)
return vec3(0.0f);
vec3 lightDir = normalize(v_lightPositionTangent0 - fragPos);
vec3 lightDir = normalize(v_lightPosition0 - fragPos);
vec3 diffuseColor = light.color;
vec3 specularColor = light.color * 0.5f;
@@ -105,10 +105,10 @@ vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 vi
vec3 ambient, diffuse, specular;
computeShading(ambientColor, diffuseColor, specularColor, lightDir, viewDir, normal, ambient, diffuse, specular);
float attenuation = computeAttenuation(v_lightPositionTangent0, fragPos, 0.032f);
// ambient *= attenuation;
// diffuse *= attenuation;
// specular *= attenuation;
float attenuation = computeAttenuation(v_lightPosition0, fragPos, 0.032f);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return ambient + diffuse + specular;
}

View File

@@ -8,10 +8,10 @@ layout(location = 3) in vec4 a_tangent;
out vec3 v_normal;
out vec2 v_texCoord;
out vec3 v_fragmentPositionTangent;
out vec3 v_fragmentPosition;
out vec4 v_fragmentPositionDirectionalLightSpace;
out vec3 v_viewPositionTangent;
out vec3 v_viewPosition;
struct DirectionalLight
{
@@ -20,7 +20,7 @@ struct DirectionalLight
vec3 color;
};
uniform DirectionalLight u_directionalLight;
out vec3 v_lightDirectionTangent;
out vec3 v_lightDirection;
struct PointLight
{
@@ -30,7 +30,7 @@ struct PointLight
};
#define NUM_POINT_LIGHTS 1
uniform PointLight u_pointLight[NUM_POINT_LIGHTS];
out vec3 v_lightPositionTangent0;
out vec3 v_lightPosition0;
uniform vec3 u_viewPosition;
@@ -45,14 +45,14 @@ void main()
vec3 N = normalize(vec3(u_modelMatrix * vec4(a_normal, 0.0f)));
T = normalize(T - dot(T, N) * N);
vec3 B = cross(N, T) * a_tangent.w;
mat3 TBN_transposed = transpose(mat3(T, B, N));
mat3 TBN = transpose(mat3(T, B, N));
v_lightDirectionTangent = TBN_transposed * u_directionalLight.direction;
v_lightPositionTangent0 = TBN_transposed * u_pointLight[0].position;
v_lightDirection = TBN * u_directionalLight.direction;
v_lightPosition0 = TBN * u_pointLight[0].position;
v_fragmentPositionTangent = TBN_transposed * vec3(u_modelMatrix * vec4(a_position, 1.0f));
v_viewPositionTangent = TBN_transposed * u_viewPosition; // seems like this is always 0 ?
v_fragmentPosition = TBN * vec3(u_modelMatrix * vec4(a_position, 1.0f));
v_viewPosition = TBN * u_viewPosition;
v_normal = a_normal;
v_normal = N;
v_texCoord = a_texCoord;
}

13
lib/CMakeLists.txt vendored
View File

@@ -1,13 +1,12 @@
option(SPDLOG_NO_EXCEPTIONS "" ON)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/entt)
option(TINYGLTF_HEADER_ONLY "" OFF)
option(TINYGLTF_INSTALL "" OFF)
option(TINYGLTF_NOEXCEPTION "" ON)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tinygltf)
option(GLFW_BUILD_DOCS "" OFF)
option(GLFW_INSTALL "" OFF)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glfw)
option(FX_GLTF_BUILD_TESTS "" OFF)
option(FX_GLTF_INSTALL "" OFF)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/fx-gltf)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/stb)

1
lib/fx-gltf vendored Submodule

Submodule lib/fx-gltf added at 7766c237ea

3
lib/stb/CMakeLists.txt Normal file
View File

@@ -0,0 +1,3 @@
add_library(stb INTERFACE)
target_include_directories(stb SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

7897
lib/stb/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -8,30 +8,29 @@ add_library(fever_engine
Mesh.cpp
Entity.cpp
Light.cpp
# Scene.cpp
Scene.cpp
FrameBuffer.cpp
Helper.cpp
resources/Resource.cpp
resources/ResourceHandler.cpp
resources/Texture.cpp
resources/Model.cpp
resources/CubeMap.cpp
util/Log.cpp
image.cpp
)
target_compile_features(fever_engine PUBLIC cxx_std_20)
target_compile_definitions(fever_engine PRIVATE SPDLOG_FMT_EXTERNAL)
target_link_libraries(
fever_engine PUBLIC
fever_engine PUBLIC
glad
glm
glfw
glm
EnTT::EnTT
fmt
pthread
spdlog
tinygltf
fx-gltf::fx-gltf
stb
)
add_executable(Fall-Fever

View File

@@ -12,37 +12,23 @@
#include <GLFW/glfw3.h>
#include <array>
#include <filesystem>
#include <fx/gltf.h>
#include <glad/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
Controller::Controller()
: m_gameWindow(std::make_shared<Window>()),
m_camera(std::make_shared<Camera>(90., m_gameWindow->aspectRatio())),
m_postProcessFrameBuffer(m_gameWindow->dimensions().first, m_gameWindow->dimensions().second,
postProcessingProgram)
m_postProcessFrameBuffer(
m_gameWindow->dimensions().first, m_gameWindow->dimensions().second, postProcessingProgram)
{
tinygltf::TinyGLTF loader;
// auto gltf = fx::gltf::LoadFromBinary("ABeautifulGame/ABeautifulGame.glb",
// {.MaxFileSize = 512 * 1024 * 1024, .MaxBufferByteLength = 512 * 1024 *
// 1024});
std::string err;
std::string warn;
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "WaterBottle/glTF/WaterBottle.gltf");
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "Duck/glTF/Duck.gltf");
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "Lantern/glTF/Lantern.gltf");
// bool ret = loader.LoadBinaryFromFile(&m_model, &err, &warn, "Camera.glb");
bool ret = loader.LoadBinaryFromFile(&m_model, &err, &warn, "ABeautifulGame/ABeautifulGame.glb");
if (!warn.empty()) {
Log::logger().warn("{}", warn);
}
if (!err.empty()) {
Log::logger().error("{}", err);
}
if (!ret) {
Log::logger().error("Failed to parse glTF");
}
auto gltf_path = std::filesystem::path("Lantern/glTF/Lantern.gltf");
auto gltf = fx::gltf::LoadFromText(gltf_path);
defaultProgram.bind();
AttributeLocations locations{};
@@ -54,11 +40,22 @@ Controller::Controller()
ShaderProgram::unbind();
if (!gltf.cameras.empty()) {
auto const &gltf_camera = gltf.cameras.at(0);
assert(gltf_camera.type == fx::gltf::Camera::Type::Perspective);
auto const &perspective = gltf_camera.perspective;
m_camera = std::make_shared<Camera>(perspective.yfov, perspective.aspectRatio);
} else {
m_camera = std::make_shared<Camera>(90., m_gameWindow->aspectRatio());
}
std::vector<Model> models;
for (auto const &mesh : m_model.meshes) {
for (auto const &mesh : gltf.meshes) {
std::vector<Mesh> meshes;
for (auto const &primitive : mesh.primitives) {
auto const &material = m_model.materials.at(primitive.material);
auto const &material = gltf.materials.at(primitive.material);
auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture.index;
auto normalTexture = material.normalTexture.index;
@@ -66,31 +63,47 @@ Controller::Controller()
// Check if texture already exists, if not load it.
if (baseColorTexture != -1 && !m_textures.contains(baseColorTexture)) {
auto const &gltf_texture = m_model.textures.at(baseColorTexture);
m_textures.emplace(baseColorTexture, Texture(gltf_texture, m_model.images, TextureType::Diffuse));
primitive_textures.push_back(m_textures.at(baseColorTexture));
auto const &gltf_texture = gltf.textures.at(baseColorTexture);
m_textures.emplace(baseColorTexture,
Texture(gltf_texture,
gltf_path.parent_path(),
gltf.images,
gltf.bufferViews,
gltf.buffers,
gltf.samplers,
TextureType::Diffuse));
primitive_textures.emplace_back(m_textures.at(baseColorTexture));
}
if (normalTexture != -1 && !m_textures.contains(normalTexture)) {
auto const &gltf_texture = m_model.textures.at(normalTexture);
m_textures.emplace(normalTexture, Texture(gltf_texture, m_model.images, TextureType::Normal));
primitive_textures.push_back(m_textures.at(normalTexture));
auto const &gltf_texture = gltf.textures.at(normalTexture);
m_textures.emplace(normalTexture,
Texture(gltf_texture,
gltf_path.parent_path(),
gltf.images,
gltf.bufferViews,
gltf.buffers,
gltf.samplers,
TextureType::Normal));
primitive_textures.emplace_back(m_textures.at(normalTexture));
}
meshes.emplace_back(Mesh({primitive, m_model, locations}, primitive_textures));
meshes.emplace_back(Mesh({primitive, gltf, locations}, primitive_textures));
}
models.emplace_back(Model(mesh.name, std::move(meshes)));
}
m_models = std::move(models);
std::vector<ModelEntity> entities;
for (auto const &node : m_model.nodes) {
for (auto const &node : gltf.nodes) {
if (node.mesh == -1) {
continue;
}
ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F), m_models[static_cast<unsigned>(node.mesh)],
defaultProgram);
ModelEntity entity(
Entity::Prototype(node.name, {}, {}, 1.0F), m_models[static_cast<unsigned>(node.mesh)], defaultProgram);
if (!node.translation.empty()) {
entity.setPosition(glm::vec3(node.translation[0], node.translation[1], node.translation[2]));

View File

@@ -6,17 +6,17 @@
#include "resources/Model.h"
#include "Entity.h"
#include "resources/Texture.h"
#include "Scene.h"
#include <glm/glm.hpp>
#include <memory>
#include <tiny_gltf.h>
#include <vector>
#include <unordered_map>
class Window;
class Scene;
class Camera;
class FrameBuffer;
class Framebuffer;
class Controller
{
@@ -32,7 +32,6 @@ private:
void update_window_dimensions();
std::shared_ptr<Window> m_gameWindow;
std::shared_ptr<Camera> m_camera;
ShaderProgram defaultProgram{{"defaultProgram", "data/shaders/basic.vert", "data/shaders/basic.frag"}};
@@ -40,11 +39,11 @@ private:
ShaderProgram postProcessingProgram{
{"postProcessingProgram", "data/shaders/postprocessing.vert", "data/shaders/postprocessing.frag"}};
FrameBuffer m_postProcessFrameBuffer;
Framebuffer m_postProcessFrameBuffer;
static constexpr unsigned MAX_FPS = 60;
tinygltf::Model m_model;
Scene m_scene;
std::vector<ModelEntity> m_entities;
std::vector<Model> m_models;

View File

@@ -2,9 +2,7 @@
#include "Mesh.h"
#include "ShaderProgram.h"
#include "VertexArray.h"
#include "resources/CubeMap.h"
#include "resources/Model.h"
#include "resources/ResourceHandler.h"
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/matrix_transform.hpp>
@@ -117,8 +115,8 @@ void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const
Skybox::Skybox(Prototype prototype, Model *cubeModel, ShaderProgram *shaderProgram)
: m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_vertexArray(cubeModel->getMesh(0)->getVertexArray())
{
m_cubeMap =
ResourceHandler::instance().registerResource<TextureCubeMap>(TextureCubeMapDescriptor{prototype.texturePath});
// m_cubeMap =
// ResourceHandler::instance().registerResource<TextureCubeMap>(TextureCubeMapDescriptor{prototype.texturePath});
}
Skybox::~Skybox()
@@ -146,10 +144,10 @@ void Skybox::draw(glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
m_shaderProgram->setUniform("u_viewProjectionMatrix", viewProjectionMatrix);
auto cubeMap = std::static_pointer_cast<TextureCubeMap>(ResourceHandler::instance().resource(m_cubeMap));
cubeMap->bind(m_shaderProgram);
m_cubeModel->getMesh(0)->drawWithoutTextures();
cubeMap->unbind();
// auto cubeMap = std::static_pointer_cast<TextureCubeMap>(ResourceHandler::instance().resource(m_cubeMap));
// cubeMap->bind(m_shaderProgram);
// m_cubeModel->getMesh(0)->drawWithoutTextures();
// cubeMap->unbind();
m_shaderProgram->unbind();
glDepthMask(GL_TRUE);

View File

@@ -1,15 +1,10 @@
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "resources/CubeMap.h"
#include "resources/ResourceHandler.h"
#include "resources/Texture.h"
#include "util/Log.h"
#include <cstddef>
AbstractFrameBuffer::~AbstractFrameBuffer()
{
}
AbstractFrameBuffer::~AbstractFrameBuffer() = default;
void AbstractFrameBuffer::bind() const
{
@@ -26,7 +21,7 @@ GLuint AbstractFrameBuffer::getFBO() const
return m_FBO;
}
FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, ShaderProgram &shaderProgram) : m_shaderProgram(shaderProgram)
Framebuffer::Framebuffer(uint32_t width, uint32_t height, ShaderProgram &shaderProgram) : m_shaderProgram(shaderProgram)
{
glGenFramebuffers(1, &m_FBO);
@@ -34,19 +29,19 @@ FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, ShaderProgram &shaderP
setExposureCorrection(true);
}
FrameBuffer::~FrameBuffer()
Framebuffer::~Framebuffer()
{
glDeleteFramebuffers(1, &m_FBO);
glDeleteTextures(1, &m_colorBuffer);
glDeleteRenderbuffers(1, &m_depthStencilBuffer);
}
GLuint FrameBuffer::getTextureId() const
GLuint Framebuffer::getTextureId() const
{
return m_colorBuffer;
}
void FrameBuffer::drawOnEntireScreen() const
void Framebuffer::drawOnEntireScreen() const
{
// Disable wireframe mode
GLint wireframe;
@@ -71,7 +66,7 @@ void FrameBuffer::drawOnEntireScreen() const
m_shaderProgram.unbind();
}
void FrameBuffer::changeDimensions(uint32_t width, uint32_t height)
void Framebuffer::changeDimensions(uint32_t width, uint32_t height)
{
// Delete old textures
glDeleteTextures(1, &m_colorBuffer);
@@ -80,7 +75,7 @@ void FrameBuffer::changeDimensions(uint32_t width, uint32_t height)
generateTextures(width, height);
}
void FrameBuffer::generateTextures(uint32_t width, uint32_t height)
void Framebuffer::generateTextures(uint32_t width, uint32_t height)
{
bind();
@@ -88,20 +83,24 @@ void FrameBuffer::generateTextures(uint32_t width, uint32_t height)
glGenTextures(1, &m_colorBuffer);
glGenRenderbuffers(1, &m_depthStencilBuffer);
glBindTexture(GL_TEXTURE_2D, m_colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, GL_RGBA,
GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
{
glBindTexture(GL_TEXTURE_2D, m_colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0,
GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
std::array<unsigned, 3> attachments = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(3, attachments.data());
glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, static_cast<GLsizei>(width),
static_cast<GLsizei>(height));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
glBindTexture(GL_TEXTURE_2D, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
Log::logger().error("Framebuffer not complete");
@@ -109,76 +108,9 @@ void FrameBuffer::generateTextures(uint32_t width, uint32_t height)
unbind();
}
void FrameBuffer::setExposureCorrection(bool exposureCorrection) const
void Framebuffer::setExposureCorrection(bool exposureCorrection) const
{
m_shaderProgram.bind();
m_shaderProgram.setUniform("u_exposureCorrection", exposureCorrection);
m_shaderProgram.unbind();
}
AbstractDepthMap::~AbstractDepthMap()
{
}
DepthMap::DepthMap(int RESOLUTION)
{
glGenFramebuffers(1, &m_FBO);
bind();
glGenTextures(1, &m_depthMap);
glBindTexture(GL_TEXTURE_2D, m_depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, RESOLUTION, RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
Log::logger().error("Framebuffer not complete");
unbind();
}
DepthMap::~DepthMap()
{
// if (m_cubeMap)
// delete m_cubeMap;
}
GLuint DepthMap::getDepthMap() const
{
return m_depthMap;
}
DepthMapCube::DepthMapCube(int resolution)
{
glGenFramebuffers(1, &m_FBO);
bind();
m_cubeMap = ResourceHandler::instance().registerResource<InternalCubeMap>(resolution);
GLuint glId = std::static_pointer_cast<InternalCubeMap>(ResourceHandler::instance().resource(m_cubeMap))->glId();
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, glId, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
Log::logger().error("Framebuffer not complete");
unbind();
}
DepthMapCube::~DepthMapCube()
{
}
GLuint DepthMapCube::getCubeMapTextureId()
{
return std::static_pointer_cast<InternalCubeMap>(ResourceHandler::instance().resource(m_cubeMap))->glId();
}

View File

@@ -20,11 +20,11 @@ protected:
GLuint m_FBO;
};
class FrameBuffer : public AbstractFrameBuffer
class Framebuffer : public AbstractFrameBuffer
{
public:
FrameBuffer(uint32_t width, uint32_t height, ShaderProgram &shaderProgram);
~FrameBuffer();
Framebuffer(uint32_t width, uint32_t height, ShaderProgram &shaderProgram);
~Framebuffer();
void drawOnEntireScreen() const;
@@ -42,34 +42,3 @@ private:
ShaderProgram &m_shaderProgram;
};
class AbstractDepthMap : public AbstractFrameBuffer
{
public:
virtual ~AbstractDepthMap() = 0;
};
// FrameBuffer without color buffer. (Shadows)
class DepthMap : public AbstractDepthMap
{
public:
DepthMap(int resolution);
~DepthMap();
GLuint getDepthMap() const;
private:
GLuint m_depthMap;
};
class DepthMapCube : public AbstractDepthMap
{
public:
DepthMapCube(int resolution);
~DepthMapCube();
GLuint getCubeMapTextureId();
private:
ResourceId m_cubeMap;
};

View File

@@ -1,197 +1,20 @@
#include "Scene.h"
#include "Controller.h"
#include "Entity.h"
#include "Light.h"
#include "ShaderProgram.h"
#include "resources/Model.h"
#include "resources/ResourceHandler.h"
#include "util/Log.h"
#include <future>
#include <memory>
#include <thread>
Scene::Scene(std::vector<std::shared_ptr<ShaderProgram>> shaderPrograms)
: m_shaderProgram(*Controller::getShaderProgramByName("defaultProgram", shaderPrograms))
#include <iostream>
static void hallo()
{
std::array modelDescriptors{
ModelDescriptor{"fallback", "data/res/models/fallback.ffo"},
ModelDescriptor{"backpack", "data/res/models/backpack.ffo"},
ModelDescriptor{"ground", "data/res/models/wood_floor.ffo"},
ModelDescriptor{"cube", "data/res/models/cube.ffo"},
ModelDescriptor{"container", "data/res/models/container.ffo"},
std::cout << "Testobj created!\n";
}
Scene::Scene()
{
struct TestComponent
{
int x;
};
{
std::vector<std::future<void>> futures;
std::mutex mutex;
auto entity = m_registry.create();
for (const auto &descriptor : modelDescriptors) {
auto sink = m_registry.on_construct<TestComponent>().before();
auto loadModel = [=, this, &mutex]() {
ResourceId model = ResourceHandler::instance().registerResource<Model>(descriptor);
Log::logger().info("Loaded model \"{}\": {}", descriptor.name, descriptor.path);
std::lock_guard<std::mutex> lock(mutex);
m_models.push_back(model);
};
futures.push_back(std::async(std::launch::async, loadModel));
}
}
// TODO: use geometry shader instead of model and load skybox before models.
Skybox::Prototype skyboxPrototype{"data/res/textures/skybox/"};
m_skybox = std::make_shared<Skybox>(
skyboxPrototype, std::static_pointer_cast<Model>(ResourceHandler::instance().resource("cube")).get(),
Controller::getShaderProgramByName("skyboxProgram", shaderPrograms).get());
Log::logger().info("Loaded skybox: {}", skyboxPrototype.texturePath);
m_skybox->initializeOnGPU();
std::array entityPrototypes{
ModelEntity::Prototype{"backpack", {0., 1., 0.}, {}, 0.6F, "backpack", "defaultProgram"},
ModelEntity::Prototype{"container", {10., 1., 0.}, {45., 45., 45.}, 1., "container", "defaultProgram"},
ModelEntity::Prototype{"ground", {}, {}, 1., "ground", "defaultProgram"},
ModelEntity::Prototype{"light", {}, {}, 1., "cube", "lightProgram"},
};
{
for (auto &prototype : entityPrototypes) {
// Get model
const Model *currentModel =
std::static_pointer_cast<Model>(ResourceHandler::instance().resource(prototype.modelName)).get();
if (!currentModel) {
// Apply fallback model (first model in vector)
currentModel = std::static_pointer_cast<Model>(ResourceHandler::instance().resource("fallback"))
.get(); // TODO rename fallbackModel
Log::logger().warn("Model could not be found by name \"{}\"", prototype.modelName);
}
// Get shaderprogram
auto currentProgram = Controller::getShaderProgramByName(prototype.shaderProgramName, shaderPrograms);
if (!currentProgram) {
currentProgram = Controller::getShaderProgramByName("basic", shaderPrograms);
}
m_entities.push_back(std::make_shared<ModelEntity>(prototype, currentModel, currentProgram.get()));
Log::logger().info("Loaded entity \"{}\" with model \"{}\"", prototype.name, prototype.modelName);
}
}
// Order important
std::array<std::unique_ptr<Light::Prototype>, 2> lightPrototypes{
std::unique_ptr<DirectionalLight::Prototype>(
new DirectionalLight::Prototype{"directionalLight", {-0.2, -1.0, -0.3}, {1., 1., 1.}, 0.25}),
std::unique_ptr<PointLight::Prototype>(
new PointLight::Prototype{"pointLight0", "light", {0., 1., 0.}, {1., 1., 1.}, 7.5}),
};
std::vector<std::shared_ptr<Light>> lights;
{
for (auto &prototype : lightPrototypes) {
std::shared_ptr<Light> currentLight;
auto directionalPrototype = dynamic_cast<DirectionalLight::Prototype *>(prototype.get());
if (directionalPrototype) {
currentLight = std::make_shared<DirectionalLight>(*directionalPrototype, &m_shaderProgram);
}
auto pointPrototype = dynamic_cast<PointLight::Prototype *>(prototype.get());
if (pointPrototype) {
currentLight = std::make_shared<PointLight>(*pointPrototype, &m_shaderProgram);
}
lights.push_back(currentLight);
Log::logger().info("Loaded light \"{}\"", prototype->name);
}
}
m_lights = lights;
}
void Scene::updatePointLight(unsigned int lightId, bool active, glm::vec3 position, glm::vec3 color, float intensity)
{
auto pointLights = getPointLights();
pointLights[lightId]->setActive(active);
pointLights[lightId]->setPosition(position);
pointLights[lightId]->setIntensity(intensity);
pointLights[lightId]->setColor(color);
}
void Scene::updateDirectionalLight(bool active, glm::vec3 direction, glm::vec3 color)
{
auto directionalLight = getDirectionalLight();
directionalLight->setActive(active);
directionalLight->setDirection(direction);
directionalLight->setColor(color);
}
void Scene::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition)
{
// Draw all entities
for (auto it = m_entities.begin(); it != m_entities.end(); it++) {
(*it)->draw(viewProjMatrix, viewPosition);
}
}
std::shared_ptr<ModelEntity> Scene::getEntityByName(const std::string &name)
{
for (auto it = m_entities.begin(); it != m_entities.end(); it++) {
if ((*it)->getUniqueName() == name) {
return *it;
}
}
Log::logger().warn("Entity could not be found by unique name \"{}\"", name);
return nullptr;
}
std::shared_ptr<ModelEntity> Scene::getEntityById(uint32_t id)
{
for (auto it = m_entities.begin(); it != m_entities.end(); it++) {
if ((*it)->getId() == id) {
return *it;
}
}
Log::logger().warn("Entity could not be found by ID \"{}\"", id);
return nullptr;
}
std::vector<std::shared_ptr<PointLight>> Scene::getPointLights()
{
std::vector<std::shared_ptr<PointLight>> temp_pointLights;
for (auto it = m_lights.begin(); it != m_lights.end(); it++) {
auto temp_pointLight = std::dynamic_pointer_cast<PointLight>(*it);
if (temp_pointLight) {
temp_pointLights.push_back(temp_pointLight);
}
}
return temp_pointLights;
}
std::shared_ptr<DirectionalLight> Scene::getDirectionalLight()
{
std::shared_ptr<DirectionalLight> temp_directionalLight;
for (auto it = m_lights.begin(); it != m_lights.end(); it++) {
temp_directionalLight = std::dynamic_pointer_cast<DirectionalLight>(*it);
if (temp_directionalLight)
break;
}
return temp_directionalLight;
}
std::vector<std::shared_ptr<ModelEntity>> Scene::getEntities()
{
return m_entities;
}
std::shared_ptr<Skybox> Scene::getSkybox()
{
return m_skybox;
}
m_registry.emplace<TestComponent>(entity, TestComponent{.x = 2});
}

View File

@@ -1,44 +1,12 @@
#pragma once
#include "resources/Resource.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <vector>
class ModelEntity;
class Light;
class PointLight;
class DirectionalLight;
class ShaderProgram;
class Skybox;
#include <entt/entt.hpp>
class Scene
{
public:
Scene(std::vector<std::shared_ptr<ShaderProgram>> shaderPrograms);
void updatePointLight(unsigned int lightId, bool active, glm::vec3 position, glm::vec3 color, float intensity);
void updateDirectionalLight(bool active, glm::vec3 direction, glm::vec3 color);
std::vector<std::shared_ptr<ModelEntity>> getEntities();
std::vector<std::shared_ptr<PointLight>> getPointLights();
std::shared_ptr<DirectionalLight> getDirectionalLight();
std::shared_ptr<Skybox> getSkybox();
std::shared_ptr<ModelEntity> getEntityByName(const std::string &name);
std::shared_ptr<ModelEntity> getEntityById(uint32_t id);
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition);
Scene();
private:
ShaderProgram &m_shaderProgram;
std::vector<ResourceId> m_models;
std::vector<std::shared_ptr<ModelEntity>> m_entities;
std::shared_ptr<Skybox> m_skybox;
// Lights
std::vector<std::shared_ptr<Light>> m_lights;
entt::registry m_registry;
};

View File

@@ -5,7 +5,25 @@
#include <cstddef>
#include <vector>
VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model,
static auto accessor_byte_size(fx::gltf::Accessor::Type accessor_type) -> std::size_t
{
switch (accessor_type) {
case fx::gltf::Accessor::Type::Scalar:
return 1;
case fx::gltf::Accessor::Type::Vec2:
return 2;
case fx::gltf::Accessor::Type::Vec3:
return 3;
case fx::gltf::Accessor::Type::Vec4:
return 4;
default:
Log::logger().warn("Unexpected accessor type: {}", static_cast<int>(accessor_type));
return 0;
}
}
VertexArray::VertexArray(fx::gltf::Primitive const &primitive,
fx::gltf::Document const &model,
AttributeLocations &locations)
{
GLuint vao{};
@@ -14,7 +32,7 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
if (!primitive.attributes.contains("TANGENT") || !primitive.attributes.contains("NORMAL")) {
Log::logger().critical("glTF scene has to include tangent and normal components!");
exit(-1);
std::terminate();
}
int position_accessor_id = primitive.attributes.at("POSITION");
@@ -23,7 +41,6 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
int tangent_accessor_id = primitive.attributes.at("TANGENT");
int indices_accessor_id = primitive.indices;
auto const &position_accessor = model.accessors.at(position_accessor_id);
auto const &normal_accessor = model.accessors.at(normal_accessor_id);
auto const &uv_accessor = model.accessors.at(uv_accessor_id);
@@ -52,115 +69,85 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
{
glGenBuffers(1, &positionVbo);
glBindBuffer(GL_ARRAY_BUFFER, positionVbo);
glBufferData(GL_ARRAY_BUFFER, position_buffer_view.byteLength,
position_buffer.data.data() + position_buffer_view.byteOffset, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER,
position_buffer_view.byteLength,
position_buffer.data.data() + position_buffer_view.byteOffset,
GL_STATIC_DRAW);
int size = 1;
if (position_accessor.type == TINYGLTF_TYPE_SCALAR) {
size = 1;
} else if (position_accessor.type == TINYGLTF_TYPE_VEC2) {
size = 2;
} else if (position_accessor.type == TINYGLTF_TYPE_VEC3) {
size = 3;
} else if (position_accessor.type == TINYGLTF_TYPE_VEC4) {
size = 4;
} else {
assert(0);
}
int position_byte_stride = position_accessor.ByteStride(position_buffer_view);
glEnableVertexAttribArray(locations.position);
glVertexAttribPointer(locations.position, size, position_accessor.componentType,
position_accessor.normalized ? GL_TRUE : GL_FALSE, position_byte_stride,
(void *)position_accessor.byteOffset);
glVertexAttribPointer(locations.position,
accessor_byte_size(position_accessor.type),
static_cast<GLenum>(position_accessor.componentType),
position_accessor.normalized ? GL_TRUE : GL_FALSE,
position_buffer_view.byteStride,
reinterpret_cast<void *>(position_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,
// performance-no-int-to-ptr)
}
GLuint normalVbo{};
{
glGenBuffers(1, &normalVbo);
glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
glBufferData(GL_ARRAY_BUFFER, normal_buffer_view.byteLength,
normal_buffer.data.data() + normal_buffer_view.byteOffset, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER,
normal_buffer_view.byteLength,
normal_buffer.data.data() + normal_buffer_view.byteOffset,
GL_STATIC_DRAW);
int size = 1;
if (normal_accessor.type == TINYGLTF_TYPE_SCALAR) {
size = 1;
} else if (normal_accessor.type == TINYGLTF_TYPE_VEC2) {
size = 2;
} else if (normal_accessor.type == TINYGLTF_TYPE_VEC3) {
size = 3;
} else if (normal_accessor.type == TINYGLTF_TYPE_VEC4) {
size = 4;
} else {
assert(0);
}
int normal_byte_stride = normal_accessor.ByteStride(normal_buffer_view);
glEnableVertexAttribArray(locations.normal);
glVertexAttribPointer(locations.normal, size, normal_accessor.componentType,
normal_accessor.normalized ? GL_TRUE : GL_FALSE, normal_byte_stride,
(void *)normal_accessor.byteOffset);
glVertexAttribPointer(locations.normal,
accessor_byte_size(normal_accessor.type),
static_cast<GLenum>(normal_accessor.componentType),
normal_accessor.normalized ? GL_TRUE : GL_FALSE,
normal_buffer_view.byteStride,
reinterpret_cast<void *>(normal_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,
// performance-no-int-to-ptr)
}
GLuint uvVbo{};
{
glGenBuffers(1, &uvVbo);
glBindBuffer(GL_ARRAY_BUFFER, uvVbo);
glBufferData(GL_ARRAY_BUFFER, uv_buffer_view.byteLength, uv_buffer.data.data() + uv_buffer_view.byteOffset,
glBufferData(GL_ARRAY_BUFFER,
uv_buffer_view.byteLength,
uv_buffer.data.data() + uv_buffer_view.byteOffset,
GL_STATIC_DRAW);
int size = 1;
if (uv_accessor.type == TINYGLTF_TYPE_SCALAR) {
size = 1;
} else if (uv_accessor.type == TINYGLTF_TYPE_VEC2) {
size = 2;
} else if (uv_accessor.type == TINYGLTF_TYPE_VEC3) {
size = 3;
} else if (uv_accessor.type == TINYGLTF_TYPE_VEC4) {
size = 4;
} else {
assert(0);
}
int uv_byte_stride = uv_accessor.ByteStride(uv_buffer_view);
glEnableVertexAttribArray(locations.uv);
glVertexAttribPointer(locations.uv, size, uv_accessor.componentType,
uv_accessor.normalized ? GL_TRUE : GL_FALSE, uv_byte_stride,
(void *)uv_accessor.byteOffset);
glVertexAttribPointer(locations.uv,
accessor_byte_size(uv_accessor.type),
static_cast<GLenum>(uv_accessor.componentType),
uv_accessor.normalized ? GL_TRUE : GL_FALSE,
uv_buffer_view.byteStride,
reinterpret_cast<void *>(uv_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,
// performance-no-int-to-ptr)
}
GLuint tangentVbo{};
{
glGenBuffers(1, &tangentVbo);
glBindBuffer(GL_ARRAY_BUFFER, tangentVbo);
glBufferData(GL_ARRAY_BUFFER, tangent_buffer_view.byteLength,
tangent_buffer.data.data() + tangent_buffer_view.byteOffset, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER,
tangent_buffer_view.byteLength,
tangent_buffer.data.data() + tangent_buffer_view.byteOffset,
GL_STATIC_DRAW);
int size = 1;
if (tangent_accessor.type == TINYGLTF_TYPE_SCALAR) {
size = 1;
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC2) {
size = 2;
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC3) {
size = 3;
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC4) {
size = 4;
} else {
assert(0);
}
int tangent_byte_stride = tangent_accessor.ByteStride(tangent_buffer_view);
glEnableVertexAttribArray(locations.tangent);
glVertexAttribPointer(locations.tangent, size, tangent_accessor.componentType,
tangent_accessor.normalized ? GL_TRUE : GL_FALSE, tangent_byte_stride,
(void *)tangent_accessor.byteOffset);
glVertexAttribPointer(locations.tangent,
accessor_byte_size(tangent_accessor.type),
static_cast<GLenum>(tangent_accessor.componentType),
tangent_accessor.normalized ? GL_TRUE : GL_FALSE,
tangent_buffer_view.byteStride,
reinterpret_cast<void *>(tangent_accessor.byteOffset)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,
// performance-no-int-to-ptr)
}
GLuint ebo{};
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_buffer_view.byteLength,
indices_buffer.data.data() + indices_buffer_view.byteOffset, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices_buffer_view.byteLength,
indices_buffer.data.data() + indices_buffer_view.byteOffset,
GL_STATIC_DRAW);
glBindVertexArray(0);

View File

@@ -3,13 +3,13 @@
#include "definitions/attribute_locations.h"
#include <glad/gl.h>
#include <tiny_gltf.h>
#include <fx/gltf.h>
#include <vector>
class VertexArray final
{
public:
VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model, AttributeLocations &locations);
VertexArray(fx::gltf::Primitive const &primitive, fx::gltf::Document const &model, AttributeLocations &locations);
VertexArray(VertexArray &&other) noexcept
: m_indicesCount(other.m_indicesCount),
m_indicesType(other.m_indicesType),
@@ -58,11 +58,11 @@ public:
static void unbind();
[[nodiscard]] auto indicesCount() const -> uint64_t { return m_indicesCount; }
[[nodiscard]] auto indicesType() const -> int { return m_indicesType; }
[[nodiscard]] auto indicesType() const -> fx::gltf::Accessor::ComponentType { return m_indicesType; }
private:
uint64_t m_indicesCount;
int m_indicesType;
fx::gltf::Accessor::ComponentType m_indicesType;
GLuint m_vao;

0
src/image.cpp Normal file
View File

5
src/image.h Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
struct Image {
};

View File

@@ -1,14 +0,0 @@
#pragma once
#include "Resource.h"
class AbstractTexture : public Resource, public GlResource
{
public:
AbstractTexture(const std::string &path) : Resource(path) {}
virtual ~AbstractTexture() = default;
protected:
uint32_t m_textureWidth;
uint32_t m_textureHeight;
};

View File

@@ -2,15 +2,52 @@
#include "../ShaderProgram.h"
#include "../util/Log.h"
Texture::Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> images, TextureType textureType)
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
Texture::Texture(fx::gltf::Texture const &texture,
std::filesystem::path const &working_directory,
std::span<fx::gltf::Image> images,
std::span<fx::gltf::BufferView> bufferViews,
std::span<fx::gltf::Buffer> buffers,
std::span<fx::gltf::Sampler> samplers,
TextureType textureType)
: m_textureType(textureType)
{
auto sampler = texture.sampler;
auto const &image = images[texture.source];
auto sampler_id = texture.sampler;
uint32_t width = image.width;
uint32_t height = image.height;
unsigned int components = image.component;
auto sampler = [samplers, sampler_id]() {
if (sampler_id != -1) {
return samplers[static_cast<unsigned>(sampler_id)];
}
return fx::gltf::Sampler{.magFilter = fx::gltf::Sampler::MagFilter::Linear,
.minFilter = fx::gltf::Sampler::MinFilter::LinearMipMapLinear,
.wrapS = fx::gltf::Sampler::WrappingMode::Repeat,
.wrapT = fx::gltf::Sampler::WrappingMode::Repeat};
}();
auto const &image = images[static_cast<unsigned>(texture.source)];
auto const &imageBufferView = bufferViews[static_cast<unsigned>(image.bufferView)];
auto const &imageBuffer = buffers[static_cast<unsigned>(imageBufferView.buffer)];
int width{};
int height{};
int components{};
auto *stbi_image = [&]() {
if (!image.uri.empty()) {
auto image_path = working_directory / image.uri;
return stbi_load(image_path.c_str(), &width, &height, &components, 0);
}
return stbi_load_from_memory(&imageBuffer.data[imageBufferView.byteOffset],
static_cast<int>(imageBufferView.byteOffset),
&width,
&height,
&components,
0);
}();
GLenum internalFormat{};
GLenum dataFormat{};
@@ -33,20 +70,29 @@ Texture::Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> im
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_2D, m_glId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, static_cast<GLint>(sampler.magFilter));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, static_cast<GLint>(sampler.minFilter));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0F);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, static_cast<GLint>(sampler.wrapS));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, static_cast<GLint>(sampler.wrapT));
glTexImage2D(GL_TEXTURE_2D, 0, static_cast<GLint>(internalFormat), static_cast<GLsizei>(width),
static_cast<GLsizei>(height), 0, dataFormat, GL_UNSIGNED_BYTE, image.image.data());
glTexImage2D(GL_TEXTURE_2D,
0,
static_cast<GLint>(internalFormat),
static_cast<GLsizei>(width),
static_cast<GLsizei>(height),
0,
dataFormat,
GL_UNSIGNED_BYTE, // read from bufferview?
stbi_image);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
Log::logger().trace(R"(Loaded texture "{}".)", image.name);
stbi_image_free(stbi_image);
Log::logger().trace(R"(Loaded texture "{}")", image.name);
}
auto Texture::textureType() const -> TextureType

View File

@@ -2,17 +2,24 @@
#include "TextureType.h"
#include <filesystem>
#include <fx/gltf.h>
#include <glad/gl.h>
#include <span>
#include <string>
#include <tiny_gltf.h>
class ShaderProgram;
class Texture
{
public:
Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> images, TextureType textureType);
Texture(fx::gltf::Texture const &texture,
std::filesystem::path const &working_directory,
std::span<fx::gltf::Image> images,
std::span<fx::gltf::BufferView> bufferViews,
std::span<fx::gltf::Buffer> buffers,
std::span<fx::gltf::Sampler> samplers,
TextureType textureType);
[[nodiscard]] auto textureType() const -> TextureType;