Commit aa2f5167 authored by Johannes Braun's avatar Johannes Braun
Browse files

added implicit Image cast

parent fb0b8400
......@@ -57,7 +57,7 @@ int main(int argc, char* argv[])
core::Context::current().callbacks().addKeyDownCallback("main_application", keyPress);
// Create a skybox from cube map.
core::Context::current().skybox()->reset(core::Skybox::collectFilesFrom(skybox_files_path));
core::Context::current().skybox()->reset(skybox_files_path);
// Load the pre-determined startup scene
loadScene(startup_scene_path, 1.f);
......
#include "texture.h"
namespace glare::core
{
Texture::Texture(Target target, StoreFormat store_format)
: m_target(target), m_handle(std::move(target)), m_format(store_format)
{ }
const Texture::Parameters& Texture::parameters() const
{
return m_latest_parameters;
}
void Texture::apply(Parameters parameters)
{
m_latest_parameters = std::move(parameters);
float anisotropy = m_latest_parameters.anisotropy;
if (anisotropy == -1.f) gl::getFloatv(gl::GetParameter::eMaxTextureMaxAnisotropy, &anisotropy);
gl::textureParameter(m_handle, gl::TextureParameter::eMaxAnisotropy, anisotropy);
gl::textureParameter(m_handle, gl::TextureParameter::eWrapR, m_latest_parameters.wrap_r);
gl::textureParameter(m_handle, gl::TextureParameter::eWrapS, m_latest_parameters.wrap_s);
gl::textureParameter(m_handle, gl::TextureParameter::eWrapT, m_latest_parameters.wrap_t);
gl::textureParameter(m_handle, gl::TextureParameter::eMagFilter, m_latest_parameters.filter_mag);
gl::textureParameter(m_handle, gl::TextureParameter::eMinFilter, m_latest_parameters.filter_min);
gl::textureParameter(m_handle, gl::TextureParameter::eCompareMode, m_latest_parameters.compare_mode);
gl::textureParameter(m_handle, gl::TextureParameter::eCompareFunc, m_latest_parameters.compare_func);
gl::textureParameter(m_handle, gl::TextureParameter::eBaseLevel, m_latest_parameters.base_level);
gl::textureParameter(m_handle, gl::TextureParameter::eMaxLevel, m_latest_parameters.max_level);
gl::generateTextureMipmap(m_handle);
}
unsigned Texture::id() const
{
return m_handle;
}
bool Texture::textureResident() const
{
return m_texture_address != 0 && gl::isTextureHandleResident(m_texture_address);
}
bool Texture::imageResident() const
{
return m_image_address != 0 && gl::isImageHandleResident(m_image_address);
}
uint64_t Texture::textureAddress() const
{
if (!textureResident())
{
m_texture_address = gl::getTextureHandle(m_handle);
gl::makeTextureHandleResident(m_texture_address);
}
assert(textureResident());
return m_texture_address;
}
uint64_t Texture::imageAddress(gl::Access access) const
{
if (!imageResident())
{
m_image_address = gl::getImageHandle(m_handle, 0, false, 0, gl::ImageUnitFormat(m_format));
gl::makeImageHandleResident(m_image_address, access);
}
assert(imageResident());
return m_image_address;
}
int Texture::samples() const
{
int s;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eSamples, &s);
return s;
}
gl::Type Texture::type() const
{
gl::Type type;
gl::getInternalFormatParameter(m_target, m_format, gl::TextureInternalFormatParameter::eTextureImageType, reinterpret_cast<int*>(&type));
return type;
}
int Texture::width() const
{
int width;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eWidth, &width);
return width;
}
int Texture::height() const
{
int height;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eHeight, &height);
return height;
}
int Texture::depth() const
{
int depth;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eDepth, &depth);
return depth;
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -10,84 +10,104 @@
namespace glare::core
{
Skybox::Skybox()
: SceneComponent("Skybox"), m_handle(std::move(gl::TextureType::eCubeMap))
Skybox::Skybox() : SceneComponent("Skybox")
{
}
Skybox::Skybox(std::vector<fs::path> faces)
: Skybox()
Skybox::Skybox(const std::vector<fs::path>& faces) : Skybox()
{
reset(faces);
}
Skybox::Skybox(const fs::path& directory) : Skybox()
{
reset(directory);
}
bool Skybox::isInitialized() const
{
return m_initialized;
}
void Skybox::reset(const fs::path& directory)
{
reset({ directory / "/posx.jpg",
directory / "/negx.jpg",
directory / "/posy.jpg",
directory / "/negy.jpg",
directory / "/posz.jpg",
directory / "/negz.jpg" });
}
void Skybox::reset(const std::vector<fs::path>& faces)
{
m_initialized = true;
m_texture = std::make_shared<Texture>(Texture::Target::eCubeMap, Texture::StoreFormat::eRGB8);
Texture::Parameters parameters;
parameters.base_level = 0;
parameters.max_level = 8;
parameters.filter_mag = gl::TextureFilterMag::eLinear;
parameters.filter_min = gl::TextureFilterMin::eLinearMipmapLinear;
parameters.wrap_r = gl::TextureWrapMode::eClampToEdge;
parameters.wrap_s = gl::TextureWrapMode::eClampToEdge;
parameters.wrap_t = gl::TextureWrapMode::eClampToEdge;
for (int face = 0; face < faces.size(); face++)
// L oad images and create a cube map texture
{
Log_Debug << "Face No " << face;
Image<uint8_t> image(faces[face]);
image.flip();
m_texture->set(gl::ImageTarget(static_cast<int>(gl::ImageTarget::eCubeMapPosX) + face), image, true);
m_texture = std::make_shared<Texture>(Texture::Target::eCubeMap, Texture::StoreFormat::eRGB8);
Texture::Parameters parameters;
parameters.base_level = 0;
parameters.max_level = 8;
parameters.filter_mag = gl::TextureFilterMag::eLinear;
parameters.filter_min = gl::TextureFilterMin::eLinearMipmapLinear;
parameters.wrap_r = gl::TextureWrapMode::eClampToEdge;
parameters.wrap_s = gl::TextureWrapMode::eClampToEdge;
parameters.wrap_t = gl::TextureWrapMode::eClampToEdge;
for (int face = 0; face < faces.size(); face++)
{
Log_Debug << "Face No " << face;
Image<uint8_t> image(faces[face]);
image.flip();
m_texture->set(gl::ImageTarget(static_cast<int>(gl::ImageTarget::eCubeMapPosX) + face), image, true);
}
m_texture->apply(parameters);
}
m_texture->apply(parameters);
std::vector<math::Vertex> triangle_vertices
// Create a screen filling triangle
{
math::Vertex{ glm::vec4(-1, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 0) },
math::Vertex{ glm::vec4(3, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(3, 0) },
math::Vertex{ glm::vec4(-1, 3, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 3) },
};
std::vector<unsigned> indices{ 0, 2, 1 };
m_triangle_mesh = std::make_shared<Mesh>(triangle_vertices, indices);
const auto vert = std::make_shared<Shader>(gl::ShaderType::eVertex, files::shader("/cubemap/triangle_skybox.vert"));
const auto frag = std::make_shared<Shader>(gl::ShaderType::eFragment, files::shader("/cubemap/triangle_skybox.frag"));
m_cubemap_shader = std::make_shared<Program>(std::vector<std::shared_ptr<Shader>>{ frag, vert });
m_cubemap_shader->uniform("u_cube_map", makeResident());
m_drawable = std::make_shared<core::BatchDrawable>([this](std::shared_ptr<Program> program) {
std::vector<math::Vertex> triangle_vertices
{
math::Vertex{ glm::vec4(-1, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 0) },
math::Vertex{ glm::vec4(3, -1, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(3, 0) },
math::Vertex{ glm::vec4(-1, 3, 0, 1), glm::vec4(0, 0, -1, 0), glm::vec2(0, 3) },
};
std::vector<unsigned> indices{ 0, 2, 1 };
m_triangle_mesh = std::make_shared<Mesh>(triangle_vertices, indices);
}
// The cube map shader will output a fragment depth of 1.
gl::depthMask(false);
gl::cullFace(gl::Face::eFront);
gl::depthFunc(gl::CompareFunc::eEqual);
m_triangle_mesh->draw();
gl::depthFunc(gl::CompareFunc::eLessEqual);
gl::cullFace(gl::Face::eBack);
gl::depthMask(true);
});
// Create shader program and drawable.
{
const auto vert = std::make_shared<Shader>(gl::ShaderType::eVertex, files::shader("/cubemap/triangle_skybox.vert"));
const auto frag = std::make_shared<Shader>(gl::ShaderType::eFragment, files::shader("/cubemap/triangle_skybox.frag"));
m_cubemap_shader = std::make_shared<Program>(std::vector<std::shared_ptr<Shader>>{ frag, vert });
m_cubemap_shader->uniform("u_cube_map", m_texture->textureAddress());
m_drawable = std::make_shared<core::BatchDrawable>([this](std::shared_ptr<Program> program) {
// The cube map shader will output a fragment depth of 1.
gl::depthMask(false);
gl::cullFace(gl::Face::eFront);
gl::depthFunc(gl::CompareFunc::eEqual);
m_triangle_mesh->draw();
gl::depthFunc(gl::CompareFunc::eLessEqual);
gl::cullFace(gl::Face::eBack);
gl::depthMask(true);
});
}
}
std::vector<fs::path> Skybox::collectFilesFrom(const fs::path &directory)
void Skybox::uniformUpdate(const Program& program, const std::string& name) const
{
return { directory / "/posx.jpg",
directory / "/negx.jpg",
directory / "/posy.jpg",
directory / "/negy.jpg",
directory / "/posz.jpg",
directory / "/negz.jpg" };
if (m_initialized)
{
program.uniform(name + ".cubemap", m_texture->textureAddress());
program.uniform(name + ".has_cubemap", 1);
}
else
{
program.uniform(name + ".color", m_background);
program.uniform(name + ".has_cubemap", 0);
}
}
void Skybox::onDraw(DrawMode mode)
......@@ -98,38 +118,8 @@ namespace glare::core
}
}
unsigned Skybox::id() const
{
return m_texture->id();
}
uint64_t Skybox::residentAddress() const
{
return m_texture->textureAddress();
}
bool Skybox::resident() const
const Texture& Skybox::texture() const
{
return m_texture->textureResident();
//return m_resident_address != 0 && gl::isTextureHandleResident(m_resident_address);
}
uint64_t Skybox::makeResident() const
{
return m_texture->textureAddress();/*
if (!resident())
{
m_resident_address = gl::getTextureHandle(m_handle);
gl::makeTextureHandleResident(m_resident_address);
}
assert(resident());
return m_resident_address;*/
}
void Skybox::makeNonResident() const
{
if (resident())
{
}
return *m_texture;
}
}
......@@ -5,6 +5,8 @@
#include <memory>
#include <vector>
#include <util/color.h>
#include <core/base/program.h>
#include <core/graph/component.h>
#include <core/rendering/batch_drawable.h>
......@@ -25,22 +27,19 @@ namespace glare::core
* \brief Loads the given paths into a cubemap texture and creates the cube mesh, as well as the cubemap shader.
* \param faces The cubemap face image paths in order: posx, negx, posy, negy, posz, negz
*/
explicit Skybox(std::vector<fs::path> faces);
explicit Skybox(const std::vector<fs::path>& faces);
explicit Skybox(const fs::path& faces);
Skybox();
~Skybox() = default;
void reset(const fs::path& directory);
void reset(const std::vector<fs::path>& faces);
static std::vector<fs::path> collectFilesFrom(const fs::path &directory);
unsigned id() const;
uint64_t residentAddress() const;
bool resident() const;
uint64_t makeResident() const;
void makeNonResident() const;
const Texture& texture() const;
bool isInitialized() const;
void uniformUpdate(const Program& program, const std::string& name) const;
protected:
/**
......@@ -51,11 +50,9 @@ namespace glare::core
private:
bool m_initialized = false;
color::rgba32f m_background{ 0.7f, 0.9f, 0.97f, 1.f };
std::shared_ptr<Texture> m_texture;
gl::handle::texture m_handle;
mutable uint64_t m_resident_address = 0;
std::shared_ptr<Program> m_cubemap_shader;
std::shared_ptr<Mesh> m_triangle_mesh;
std::shared_ptr<BatchDrawable> m_drawable;
......
......@@ -116,7 +116,7 @@ namespace glare::core
m_texture_renderer->shader().storageBuffer("lightsBuffer", *m_lights_buffer);
if (m_skybox->isInitialized())
m_texture_renderer->shader().uniform("environment", m_skybox->makeResident());
m_texture_renderer->shader().uniform("environment", m_skybox->texture().textureAddress());
m_texture_renderer->shader().uniform("u_ssao_texture", m_temporary_framebuffer_01->attachment(gl::Attachment::eColor0).textureAddress());
m_texture_renderer->shader().uniform("u_view", core::Context::current().camera()->viewMatrix());
......
......@@ -81,6 +81,9 @@ namespace glare::core
// Or load an image from HDD as single-sample image
explicit Image(const std::experimental::filesystem::path& path);
// Or convert another image
template<typename Src> Image(const Image<Src>& other);
void save(const fs::path& path);
void flip();
......@@ -94,6 +97,7 @@ namespace glare::core
int samples() const;
const std::vector<TBase>& data() const;
int dimensions() const;
const Extents& extents() const;
private:
Extents m_extents;
......@@ -152,6 +156,39 @@ namespace glare::core
flip();
}
template <typename TBase>
template<typename Src> Image<TBase>::Image(const Image<Src>& other)
: m_extents(other.extents()), m_components(other.components()), m_samples(other.samples())
{
m_data.resize(other.data().size());
for (int index = 0; index < other.data().size(); ++index)
{
if constexpr(std::is_same_v<TBase, Src>)
{
m_data[index] = other.data()[index];
}
else if constexpr(std::is_same_v<TBase, float>)
{
m_data[index] = static_cast<TBase>(glm::clamp(static_cast<float>(other.data()[index]), 0.f, 1.f) / static_cast<float>(std::numeric_limits<Src>::max()));
}
else if constexpr(std::is_same_v<Src, float>)
{
m_data[index] = static_cast<TBase>(glm::clamp(static_cast<float>(other.data()[index]), 0.f, 1.f) * static_cast<float>(std::numeric_limits<TBase>::max()));
}
else
{
m_data[index] = static_cast<TBase>(glm::clamp(conversionFactor<Src, TBase>() * other.data()[index], static_cast<float>(std::numeric_limits<Src>::lowest()), static_cast<float>(std::numeric_limits<Src>::max())));
}
}
}
template <typename TBase>
const Extents& Image<TBase>::extents() const
{
return m_extents;
}
template <typename TBase>
std::tuple<TBase&, TBase&, TBase&, TBase&> Image<TBase>::operator[](Extents pixel)
{
......
......@@ -25,10 +25,9 @@ namespace glare::raytrace
void SkyboxCollector::apply(core::Program &program)
{
if (m_skybox && m_skybox->isInitialized())
if (m_skybox)
{
program.uniform("u_environment.cubemap", m_skybox->makeResident());
program.uniform("u_environment.has_cubemap", 1);
program.uniformStruct("u_environment", *m_skybox);
}
else
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment