Commit 8035abe0 authored by Johannes Braun's avatar Johannes Braun
Browse files

Even more Texture fixes. Issues when saving rgba32f to rgba8u png

parent e317d970
......@@ -72,7 +72,7 @@ uint getBounceThreshold(uint id)
void writeRenderTarget(int id, vec4 color)
{
Trace trace = traces_data[id];
u_render_target.imageStore(ivec2(trace.ray.px, trace.ray.py), color);
u_render_target.imageStore(ivec2(trace.ray.px, trace.ray.py), vec4(color.rgb, 1));
}
void writeColorStore(const in Ray ray, const in vec3 rgb_color, float clamp_color)
......
This diff is collapsed.
......@@ -29,22 +29,22 @@ namespace glare::core
for (auto &&texture : m_color_attachments) {
if (m_samples == 1)
{
texture.second->resize<color::rgba32f>(gl::TextureImageTarget2D::e2D, width, height, 4, gl::TextureInternalFormat::eRGBA32Float);
texture.second->set(gl::ImageTarget::e2D, Image<float>({ static_cast<int>(width), static_cast<int>(height) }, 4));
}
else
{
texture.second->resize<color::rgba32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, width, height, samples, 4, gl::TextureInternalFormat::eRGBA32Float);
texture.second->set(gl::ImageTargetMultisample::e2DMultisample, Image<float>({ static_cast<int>(width), static_cast<int>(height) }, 4, samples));
}
}
if (m_depth_attachment) {
if (m_samples == 1)
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTarget2D::e2D, width, height, 4, gl::TextureInternalFormat::eDepthComponent32Float);
m_depth_attachment->set(gl::ImageTarget::e2D, Image<float>({ static_cast<int>(width), static_cast<int>(height) }, 4));
}
else
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, width, height, samples, 4, gl::TextureInternalFormat::eDepthComponent32Float);
m_depth_attachment->set(gl::ImageTargetMultisample::e2DMultisample, Image<float>({ static_cast<int>(width), static_cast<int>(height) }, 4, samples));
}
}
}
......@@ -67,36 +67,45 @@ namespace glare::core
void Framebuffer::attach(gl::Attachment att)
{
Texture::Parameters parameters;
parameters.filter_mag = gl::TextureFilterMag::eLinear;
parameters.filter_min = gl::TextureFilterMin::eLinear;
switch (att)
{
case gl::Attachment::eDepth:
case gl::Attachment::eDepthStencil:
m_depth_attachment = std::make_shared<Texture>();
if (m_samples == 1)
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTarget2D::e2D, m_width, m_height, 4, gl::TextureInternalFormat::eDepthComponent32Float);
m_depth_attachment = std::make_shared<Texture>(Texture::Target::e2D, Texture::StoreFormat::eDepthComponent32Float);
m_depth_attachment->set(gl::ImageTarget::e2D, Image<float>({ m_width, m_height }, 4), parameters);
}
else
{
m_depth_attachment->resize<color::r32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, m_width, m_height, m_samples, 4, gl::TextureInternalFormat::eDepthComponent32Float);
m_depth_attachment = std::make_shared<Texture>(Texture::Target::e2DMultisample, Texture::StoreFormat::eDepthComponent32Float);
m_depth_attachment->set(gl::ImageTargetMultisample::e2DMultisample, Image<float>({ m_width, m_height }, 4, m_samples), parameters);
}
gl::namedFramebufferTexture(m_handle, att, m_depth_attachment->id(), 0);
break;
default:
{
std::shared_ptr<Texture> new_attachment = std::make_shared<Texture>();
unsigned new_id;
if (m_samples == 1)
{
new_attachment->resize<color::rgba32f>(gl::TextureImageTarget2D::e2D, m_width, m_height, 4, gl::TextureInternalFormat::eRGBA32Float);
auto new_attachment = std::make_shared<Texture>(Texture::Target::e2D, Texture::StoreFormat::eRGBA32Float);
new_attachment->set(gl::ImageTarget::e2D, Image<float>({ m_width, m_height }, 4), parameters);
m_color_attachments.emplace(att, new_attachment);
new_id = new_attachment->id();
}
else
{
new_attachment->resize<color::rgba32f>(gl::TextureImageTargetMultisample2D::e2DMultisample, m_width, m_height, m_samples, 4, gl::TextureInternalFormat::eRGBA32Float);
auto new_attachment = std::make_shared<Texture>(Texture::Target::e2DMultisample, Texture::StoreFormat::eRGBA32Float);
new_attachment->set(gl::ImageTargetMultisample::e2DMultisample, Image<float>({ m_width, m_height }, 4, m_samples), parameters);
m_color_attachments.emplace(att, new_attachment);
new_id = new_attachment->id();
}
m_color_attachments.emplace(att, new_attachment);
putAttachment(att, new_attachment->id());
putAttachment(att, new_id);
} break;
}
}
......@@ -130,8 +139,10 @@ namespace glare::core
if (std::find(m_draw_buffers.begin(), m_draw_buffers.end(), attachment) == m_draw_buffers.end()) {
m_draw_buffers.push_back(attachment);
gl::namedFramebufferDrawBuffers(m_handle, m_draw_buffers);
}
if (auto status = gl::checkNamedFramebufferStatus(m_handle, gl::FramebufferTarget::eDraw) != gl::FramebufferStatus::eComplete)
}
gl::FramebufferStatus status;
if ((status = gl::checkNamedFramebufferStatus(m_handle, gl::FramebufferTarget::eDraw)) != gl::FramebufferStatus::eComplete)
Log_Error << "An error occured when generating the framebuffer: " << static_cast<int>(status);
}
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
// --- EXTERN ---------------------------------------------
#include <util/log.h>
#include <util/opengl.h>
#include <core/res/texture.h>
#include <core/base/texture.h>
// --- INTERN ---------------------------------------------
......
#ifndef INCLUDE_TEXTURE_H
#define INCLUDE_TEXTURE_H
#include <cassert>
#include "core/res/image.h"
#include "util/opengl.h"
namespace glare::core
{
struct Texture
{
using Target = gl::TextureType;
using SubTarget = gl::ImageTarget;
using StoreFormat = gl::TextureInternalFormat;
using SubTargetMultisample = gl::ImageTargetMultisample;
struct Parameters
{
gl::TextureWrapMode wrap_r = gl::TextureWrapMode::eRepeat;
gl::TextureWrapMode wrap_s = gl::TextureWrapMode::eRepeat;
gl::TextureWrapMode wrap_t = gl::TextureWrapMode::eRepeat;
gl::TextureFilterMin filter_min = gl::TextureFilterMin::eLinearMipmapLinear;
gl::TextureFilterMag filter_mag = gl::TextureFilterMag::eLinear;
gl::TextureCompareMode compare_mode = gl::TextureCompareMode::eRToTexture;
gl::CompareFunc compare_func = gl::CompareFunc::eLess;
float anisotropy = -1.f;
};
// General initialization
Texture(Target target, StoreFormat store_format)
: m_target(target), m_handle(std::move(target)), m_format(store_format)
{
}
// Direct initialization for either 1D, 2D or 3D target.
template<typename T> Texture(const Image<T>& image)
: Texture([&image]() {
switch (image.dimensions())
{
case 1: return Target::e1D;
case 2: return Target::e2D;
case 3: return Target::e3D;
default: return Target::e2D;
}
}(), getFormat(image))
{
switch (m_target)
{
case Target::e1D:
set(SubTarget::e1D, image, m_latest_parameters);
break;
case Target::e2D:
set(SubTarget::e2D, image, m_latest_parameters);
break;
case Target::e3D:
set(SubTarget::e3D, image, m_latest_parameters);
break;
default: throw std::invalid_argument("Target not defined as 1D, 2D or 3D. How exactly did you manage to come to this point???");
}
}
template<typename T>
Image<T> get()
{
if (m_target != gl::TextureType::e2D || m_components == -1)
{
throw std::invalid_argument("You cannot download this texture.");
}
int texture_width = width();
int texture_height = height();
int components = m_components;
auto texture_type = type();
int type_size = static_cast<int>([](gl::Type type)
{
switch (type)
{
case gl::Type::eByte:
return sizeof(int8_t);
case gl::Type::eUByte:
case gl::Type::eUInt_8_8_8_8:
case gl::Type::eUInt_8_8_8_8_rev:
return sizeof(uint8_t);
case gl::Type::eInt:
return sizeof(int32_t);
case gl::Type::eUInt:
return sizeof(uint32_t);
case gl::Type::eFloat:
return sizeof(float);
default: throw std::invalid_argument("Texture format not valid.");
}
}(texture_type));
gl::TextureFormat texture_format = [](int components, gl::Type type)
{
switch (components)
{
case 1: if (type == gl::Type::eInt || type == gl::Type::eUInt) return gl::TextureFormat::eRedInt;
else return gl::TextureFormat::eRed;
case 2: if (type == gl::Type::eInt || type == gl::Type::eUInt) return gl::TextureFormat::eRGInt;
else return gl::TextureFormat::eRG;
case 3: if (type == gl::Type::eInt || type == gl::Type::eUInt) return gl::TextureFormat::eRGBInt;
else return gl::TextureFormat::eRGB;
case 4: if (type == gl::Type::eInt || type == gl::Type::eUInt) return gl::TextureFormat::eRGBAInt;
else return gl::TextureFormat::eRGBA;
default: throw std::invalid_argument("Texture format not valid.");
}
}(components, texture_type);
std::vector<uint8_t> data(texture_width * texture_height * components * type_size);
std::vector<T> converted(texture_width*texture_height*components);
gl::getTextureImage(m_handle, 0, texture_format, texture_type, data.size(), data.data());
for (int i = 0; i < texture_width*texture_height*components; ++i)
{
switch (texture_type)
{
case gl::Type::eByte:
converted[i] = clampConvert<int8_t, T>(data.data(), i);// static_cast<T>(glm::clamp(conversionFactor<int8_t, T>() * reinterpret_cast<int8_t*>(data.data())[i], std::numeric_limits<int8_t>::lowest(), std::numeric_limits<int8_t>::max()));
break;
case gl::Type::eUByte:
case gl::Type::eUInt_8_8_8_8:
case gl::Type::eUInt_8_8_8_8_rev:
converted[i] = clampConvert<uint8_t, T>(data.data(), i);// static_cast<T>(glm::clamp(conversionFactor<uint8_t, T>() * reinterpret_cast<uint8_t*>(data.data())[i], std::numeric_limits<uint8_t>::lowest(), std::numeric_limits<uint8_t>::max()));
break;
case gl::Type::eShort:
converted[i] = clampConvert<int16_t, T>(data.data(), i); //static_cast<T>(glm::clamp(conversionFactor<int16_t, T>() * reinterpret_cast<int16_t*>(data.data())[i], std::numeric_limits<int16_t>::lowest(), std::numeric_limits<int16_t>::max()));
break;
case gl::Type::eUShort:
converted[i] = clampConvert<uint16_t, T>(data.data(), i);// static_cast<T>(glm::clamp(conversionFactor<uint16_t, T>() * reinterpret_cast<uint16_t*>(data.data())[i], std::numeric_limits<uint16_t>::lowest(), std::numeric_limits<uint16_t>::max()));
break;
case gl::Type::eInt:
converted[i] = clampConvert<int32_t, T>(data.data(), i);// static_cast<T>(glm::clamp(conversionFactor<int32_t, T>() * reinterpret_cast<int32_t*>(data.data())[i], std::numeric_limits<int32_t>::lowest(), std::numeric_limits<int32_t>::max()));
break;
case gl::Type::eUInt:
converted[i] = clampConvert<uint32_t, T>(data.data(), i);// static_cast<T>(glm::clamp(conversionFactor<uint32_t, T>() * reinterpret_cast<uint32_t*>(data.data())[i], std::numeric_limits<uint32_t>::lowest(), std::numeric_limits<uint32_t>::max()));
break;
case gl::Type::eFloat:
converted[i] = static_cast<T>(conversionFactor<float, T>() * reinterpret_cast<float*>(data.data())[i]);
break;
default: throw std::invalid_argument("Texture format not valid.");
}
}
return Image<T>({ texture_width, texture_height }, components, converted);
}
template<typename T> void set(SubTargetMultisample t, const Image<T>& image)
{
set(t, image, m_latest_parameters);
}
// up until the set methods, no openGL is needed yet.
// Upload an image
template<typename T> void set(SubTargetMultisample t, const Image<T>& image, Parameters parameters)
{
assert(image.samples() != 0);
m_components = image.components();
gl::pixelStorei(gl::PixelStoreAlignment::eUnpack, 1);
gl::textureImage(m_handle, t, image.samples(), m_format, { image.width(), image.height(), image.depth() });
apply(std::move(parameters));
}
template<typename T> void set(SubTarget t, const Image<T>& image)
{
set(t, image, m_latest_parameters);
}
// up until the set methods, no openGL is needed yet.
// Upload an image
template<typename T> void set(SubTarget t, const Image<T>& image, Parameters parameters)
{
set(t, 0, image, std::move(parameters));
}
// Upload an image
template<typename T> void set(SubTarget t, int level, const Image<T>& image, Parameters parameters)
{
// Don't allow level parameter on MS textures.
// images are multisampled if sample count is not 0.
assert(image.samples() == 0);
gl::TextureFormat texture_format = [](int components, StoreFormat format)
{
switch (components)
{
case 1: if constexpr(std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>) return gl::TextureFormat::eRedInt;
else return !(format == StoreFormat::eDepthComponent32Float || format == StoreFormat::eDepthComponent) ? gl::TextureFormat::eRed : gl::TextureFormat::eDepthComponent;
case 2: if constexpr(std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>) return gl::TextureFormat::eRGInt;
else return !(format == StoreFormat::eDepthComponent32Float || format == StoreFormat::eDepthComponent) ? gl::TextureFormat::eRG : gl::TextureFormat::eDepthComponent;
case 3: if constexpr(std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>) return gl::TextureFormat::eRGBInt;
else return !(format == StoreFormat::eDepthComponent32Float || format == StoreFormat::eDepthComponent) ? gl::TextureFormat::eRGB : gl::TextureFormat::eDepthComponent;
case 4: if constexpr(std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>) return gl::TextureFormat::eRGBAInt;
else return !(format == StoreFormat::eDepthComponent32Float || format == StoreFormat::eDepthComponent) ? gl::TextureFormat::eRGBA : gl::TextureFormat::eDepthComponent;
default: throw std::invalid_argument("Texture format not valid.");
}
}(image.components(), m_format);
m_components = image.components();
gl::pixelStorei(gl::PixelStoreAlignment::eUnpack, 1);
gl::textureImage(m_handle, t, level, m_format, texture_format, { image.width(), image.height(), image.depth() }, image.data().empty() ? nullptr : image.data().data());
apply(std::move(parameters));
}
const Parameters& parameters() const
{
return m_latest_parameters;
}
void 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::generateTextureMipmap(m_handle);
}
unsigned id() const
{
return m_handle;
}
bool textureResident() const
{
return m_texture_address != 0 && gl::isTextureHandleResident(m_texture_address);
}
bool imageResident() const
{
return m_image_address != 0 && gl::isImageHandleResident(m_image_address);
}
uint64_t textureAddress() const
{
if (!textureResident())
{
m_texture_address = gl::getTextureHandle(m_handle);
gl::makeTextureHandleResident(m_texture_address);
}
assert(textureResident());
return m_texture_address;
}
uint64_t 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 samples() const
{
int s;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eSamples, &s);
return s;
}
gl::Type type() const
{
gl::Type type;
gl::getInternalFormatParameter(m_target, m_format, gl::TextureInternalFormatParameter::eTextureImageType, reinterpret_cast<int*>(&type));
return type;
}
int width() const
{
int width;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eWidth, &width);
return width;
}
int height() const
{
int height;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eHeight, &height);
return height;
}
int depth() const
{
int depth;
gl::getTextureLevelParameteriv(m_handle, 0, gl::TextureLevelParameter::eDepth, &depth);
return depth;
}
private:
template<typename From, typename To>
static To clampConvert(const void* data, int index)
{
return static_cast<To>(glm::clamp<float>(conversionFactor<From, To>() * reinterpret_cast<const From*>(data)[index], static_cast<float>(std::numeric_limits<From>::lowest()), static_cast<float>(std::numeric_limits<From>::max())));
}
template<typename T>
static StoreFormat getFormat(const Image<T>& image)
{
switch (image.components())
{
case 1:
if constexpr(std::is_same_v<T, float>) return gl::TextureInternalFormat::eR32Float;
else if constexpr(std::is_same_v<T, uint8_t>) return gl::TextureInternalFormat::eR8;
else if constexpr(std::is_same_v<T, uint16_t>) return gl::TextureInternalFormat::eR16UInt;
else if constexpr(std::is_same_v<T, uint32_t>) return gl::TextureInternalFormat::eR32UInt;
else if constexpr(std::is_same_v<T, int8_t>) return gl::TextureInternalFormat::eR8Int;
else if constexpr(std::is_same_v<T, int16_t>) return gl::TextureInternalFormat::eR16Int;
else if constexpr(std::is_same_v<T, int32_t>) return gl::TextureInternalFormat::eR32Int;
case 2:
if constexpr(std::is_same_v<T, float>) return gl::TextureInternalFormat::eRG32Float;
else if constexpr(std::is_same_v<T, uint8_t>) return gl::TextureInternalFormat::eRG8;
else if constexpr(std::is_same_v<T, uint16_t>) return gl::TextureInternalFormat::eRG16UInt;
else if constexpr(std::is_same_v<T, uint32_t>) return gl::TextureInternalFormat::eRG32UInt;
else if constexpr(std::is_same_v<T, int8_t>) return gl::TextureInternalFormat::eRG8Int;
else if constexpr(std::is_same_v<T, int16_t>) return gl::TextureInternalFormat::eRG16Int;
else if constexpr(std::is_same_v<T, int32_t>) return gl::TextureInternalFormat::eRG32Int;
case 3:
if constexpr(std::is_same_v<T, float>) return gl::TextureInternalFormat::eRGB32Float;
else if constexpr(std::is_same_v<T, uint8_t>) return gl::TextureInternalFormat::eRGB8;
else if constexpr(std::is_same_v<T, uint16_t>) return gl::TextureInternalFormat::eRGB16UInt;
else if constexpr(std::is_same_v<T, uint32_t>) return gl::TextureInternalFormat::eRGB32UInt;
else if constexpr(std::is_same_v<T, int8_t>) return gl::TextureInternalFormat::eRGB8Int;
else if constexpr(std::is_same_v<T, int16_t>) return gl::TextureInternalFormat::eRGB16Int;
else if constexpr(std::is_same_v<T, int32_t>) return gl::TextureInternalFormat::eRGB32Int;
case 4:
if constexpr(std::is_same_v<T, float>) return gl::TextureInternalFormat::eRGBA32Float;
else if constexpr(std::is_same_v<T, uint8_t>) return gl::TextureInternalFormat::eRGBA8;
else if constexpr(std::is_same_v<T, uint16_t>) return gl::TextureInternalFormat::eRGBA16UInt;
else if constexpr(std::is_same_v<T, uint32_t>) return gl::TextureInternalFormat::eRGBA32UInt;
else if constexpr(std::is_same_v<T, int8_t>) return gl::TextureInternalFormat::eRGBA8Int;
else if constexpr(std::is_same_v<T, int16_t>) return gl::TextureInternalFormat::eRGBA16Int;
else if constexpr(std::is_same_v<T, int32_t>) return gl::TextureInternalFormat::eRGBA32Int;
throw std::invalid_argument("Using images other than 32 bit float and integral types is not yet implemented");
default:
throw std::invalid_argument("Malformed image! Component count not in range 1 to 4.");
}
}
int m_components = -1;
Target m_target;
StoreFormat m_format;
Parameters m_latest_parameters;
gl::handle::texture m_handle;
mutable uint64_t m_texture_address = 0;
mutable uint64_t m_image_address = 0;
};
}
#endif //!INCLUDE_TEXTURE_H
\ No newline at end of file
......@@ -100,7 +100,7 @@ namespace glare::core
{
ShadowMapData shadow_map;
shadow_map.available = m_shadow_map_renderer ? 1 : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().attachment(gl::Attachment::eDepth).residentTextureAddress() : 0;
shadow_map.map = shadow_map.available ? m_shadow_map_renderer->framebuffer().attachment(gl::Attachment::eDepth).textureAddress() : 0;
shadow_map.matrix = shadow_map.available ? m_shadow_map_renderer->matrix() : glm::mat4(1.f);
return{ buildLight(), shadow_map };
}
......
......@@ -3,6 +3,7 @@
#include <core/graph/component.h>
#include <core/objects/shadow_map.h>
#include <util/color.h>
namespace glare::core
{
......
......@@ -69,33 +69,33 @@ namespace glare::core
{
program.uniform(name + ".base.value", base.value);
if (base.texture)
program.uniform(name + ".base.texture", base.texture->residentTextureAddress());
program.uniform(name + ".base.texture", base.texture->textureAddress());
program.uniform(name + ".base.texture_available", static_cast<uint32_t>(static_cast<bool>(base.texture)));
program.uniform(name + ".roughness.value", roughness.value);
if (roughness.texture)
program.uniform(name + ".roughness.texture", roughness.texture->residentTextureAddress());
program.uniform(name + ".roughness.texture", roughness.texture->textureAddress());
program.uniform(name + ".roughness.texture_available", static_cast<uint32_t>(static_cast<bool>(roughness.texture)));
program.uniform(name + ".metallic.value", metallic.value);
if (metallic.texture)
program.uniform(name + ".metallic.texture", metallic.texture->residentTextureAddress());
program.uniform(name + ".metallic.texture", metallic.texture->textureAddress());
program.uniform(name + ".metallic.texture_available", static_cast<uint32_t>(static_cast<bool>(metallic.texture)));
program.uniform(name + ".transmission.value", transmissive.value);
if (transmissive.texture)
program.uniform(name + ".transmission.texture", transmissive.texture->residentTextureAddress());
program.uniform(name + ".transmission.texture", transmissive.texture->textureAddress());
program.uniform(name + ".transmission.texture_available", static_cast<uint32_t>(static_cast<bool>(transmissive.texture)));
program.uniform(name + ".emission.value", emission.value);
if (emission.texture)
program.uniform(name + ".emission.texture", emission.texture->residentTextureAddress());
program.uniform(name + ".emission.texture", emission.texture->textureAddress());
program.uniform(name + ".emission.texture_available", static_cast<uint32_t>(static_cast<bool>(emission.texture)));
if (map_normal)
program.uniform(name + ".normal_map", map_normal->residentTextureAddress());
program.uniform(name + ".normal_map", map_normal->textureAddress());
if (map_displacement)
program.uniform(name + ".displacement_map", map_displacement->residentTextureAddress());
program.uniform(name + ".displacement_map", map_displacement->textureAddress());
program.uniform(name + ".has_displacement_map", static_cast<bool>(map_displacement));
program.uniform(name + ".has_normal_map", static_cast<bool>(emission.texture));
......
......@@ -5,7 +5,7 @@
#include <atomic>
#include <core/base/program.h>
#include <core/res/texture.h>
#include <core/base/texture.h>
namespace glare::core
{
......
......@@ -45,12 +45,12 @@ namespace glare::core
m_lights_buffer = std::make_unique<Buffer>();
//Update all uniforms that won't change anymore...
m_texture_renderer->shader().uniform("u_gbuffer.base_ior", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor0).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.rough_metallic_transmit_emit", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor1).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.normal", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor2).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.modelview_position", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor3).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.world_position", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor4).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.depth", m_gbuffer_framebuffer->attachment(gl::Attachment::eDepth).residentTextureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.base_ior", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor0).textureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.rough_metallic_transmit_emit", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor1).textureAddress());
m_texture_renderer->shader().uniform("u_gbuffer.normal", m_gbuffer_framebuffer->attachment(gl::Attachment::eColor2).textureAddress());