Browse Source

Add color space parameter to texture creation

master
C. J. Howard 4 years ago
parent
commit
a6fa3c1802
7 changed files with 107 additions and 20 deletions
  1. +6
    -4
      src/game/bootloader.cpp
  2. +30
    -0
      src/rasterizer/color-space.hpp
  3. +26
    -5
      src/rasterizer/texture-2d.cpp
  4. +24
    -7
      src/rasterizer/texture-2d.hpp
  5. +9
    -2
      src/renderer/passes/material-pass.cpp
  6. +8
    -1
      src/renderer/passes/material-pass.hpp
  7. +4
    -1
      src/resources/texture-2d-loader.cpp

+ 6
- 4
src/game/bootloader.cpp View File

@ -490,6 +490,7 @@ void setup_rendering(game_context* ctx)
ctx->overworld_material_pass->set_fallback_material(ctx->fallback_material); ctx->overworld_material_pass->set_fallback_material(ctx->fallback_material);
ctx->overworld_material_pass->shadow_map_pass = ctx->overworld_shadow_map_pass; ctx->overworld_material_pass->shadow_map_pass = ctx->overworld_shadow_map_pass;
ctx->overworld_material_pass->shadow_map = ctx->shadow_map_depth_texture; ctx->overworld_material_pass->shadow_map = ctx->shadow_map_depth_texture;
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->overworld_material_pass);
ctx->overworld_outline_pass = new outline_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager); ctx->overworld_outline_pass = new outline_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->overworld_outline_pass->set_outline_width(0.25f); ctx->overworld_outline_pass->set_outline_width(0.25f);
ctx->overworld_outline_pass->set_outline_color(float4{1.0f, 1.0f, 1.0f, 1.0f}); ctx->overworld_outline_pass->set_outline_color(float4{1.0f, 1.0f, 1.0f, 1.0f});
@ -516,6 +517,7 @@ void setup_rendering(game_context* ctx)
ctx->underworld_clear_pass->set_cleared_buffers(true, true, false); ctx->underworld_clear_pass->set_cleared_buffers(true, true, false);
ctx->underworld_material_pass = new material_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager); ctx->underworld_material_pass = new material_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->underworld_material_pass->set_fallback_material(ctx->fallback_material); ctx->underworld_material_pass->set_fallback_material(ctx->fallback_material);
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->underworld_material_pass);
shader_program* underworld_final_shader = ctx->resource_manager->load<shader_program>("underground-final.glsl"); shader_program* underworld_final_shader = ctx->resource_manager->load<shader_program>("underground-final.glsl");
ctx->underworld_final_pass = new simple_render_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), underworld_final_shader); ctx->underworld_final_pass = new simple_render_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), underworld_final_shader);
ctx->underground_color_texture_property = ctx->underworld_final_pass->get_material()->add_property<const texture_2d*>("color_texture"); ctx->underground_color_texture_property = ctx->underworld_final_pass->get_material()->add_property<const texture_2d*>("color_texture");
@ -875,8 +877,6 @@ void setup_systems(game_context* ctx)
ctx->ui_system->set_tool_menu_control(ctx->control_system->get_tool_menu_control()); ctx->ui_system->set_tool_menu_control(ctx->control_system->get_tool_menu_control());
event_dispatcher->subscribe<mouse_moved_event>(ctx->ui_system); event_dispatcher->subscribe<mouse_moved_event>(ctx->ui_system);
event_dispatcher->subscribe<window_resized_event>(ctx->ui_system); event_dispatcher->subscribe<window_resized_event>(ctx->ui_system);
} }
void setup_controls(game_context* ctx) void setup_controls(game_context* ctx)
@ -1167,9 +1167,8 @@ void setup_callbacks(game_context* ctx)
( (
[ctx](double t, double dt) [ctx](double t, double dt)
{ {
// Update tweens
ctx->time_tween->update();
(*ctx->time_tween)[1] = t; (*ctx->time_tween)[1] = t;
ctx->overworld_scene->update_tweens(); ctx->overworld_scene->update_tweens();
ctx->underworld_scene->update_tweens(); ctx->underworld_scene->update_tweens();
ctx->ui_scene->update_tweens(); ctx->ui_scene->update_tweens();
@ -1212,6 +1211,9 @@ void setup_callbacks(game_context* ctx)
ctx->application_controls->update(); ctx->application_controls->update();
ctx->menu_controls->update(); ctx->menu_controls->update();
ctx->camera_controls->update(); ctx->camera_controls->update();
// Update tweens
ctx->time_tween->update();
} }
); );

+ 30
- 0
src/rasterizer/color-space.hpp View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2020 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_COLOR_SPACE_HPP
#define ANTKEEPER_COLOR_SPACE_HPP
enum class color_space
{
linear, ///< Linear color space
srgb ///< sRGB color space
};
#endif // ANTKEEPER_COLOR_SPACE_HPP

+ 26
- 5
src/rasterizer/texture-2d.cpp View File

@ -47,7 +47,7 @@ static constexpr GLenum pixel_type_lut[] =
GL_FLOAT GL_FLOAT
}; };
static constexpr GLenum internal_format_lut[][8] =
static constexpr GLenum linear_internal_format_lut[][8] =
{ {
{GL_NONE, GL_NONE, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT32, GL_NONE, GL_DEPTH_COMPONENT32F}, {GL_NONE, GL_NONE, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT32, GL_NONE, GL_DEPTH_COMPONENT32F},
@ -60,7 +60,18 @@ static constexpr GLenum internal_format_lut[][8] =
{GL_RGB8, GL_RGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F}, {GL_RGB8, GL_RGB8, GL_RGB16, GL_RGB16, GL_RGB32F, GL_RGB32F, GL_RGB16F, GL_RGB32F},
{GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F}, {GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F},
{GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F} {GL_RGBA8, GL_RGBA8, GL_RGBA16, GL_RGBA16, GL_RGBA32F, GL_RGBA32F, GL_RGBA16F, GL_RGBA32F}
};
static constexpr GLenum srgb_internal_format_lut[][8] =
{
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8, GL_SRGB8},
{GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8},
{GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8}
}; };
static constexpr GLint swizzle_mask_lut[][4] = static constexpr GLint swizzle_mask_lut[][4] =
@ -98,7 +109,7 @@ static constexpr GLenum mag_filter_lut[] =
GL_LINEAR GL_LINEAR
}; };
texture_2d::texture_2d(int width, int height, ::pixel_type type, ::pixel_format format, const void* data):
texture_2d::texture_2d(int width, int height, ::pixel_type type, ::pixel_format format, ::color_space color_space, const void* data):
gl_texture_id(0), gl_texture_id(0),
dimensions({0, 0}), dimensions({0, 0}),
wrapping({texture_wrapping::repeat, texture_wrapping::repeat}), wrapping({texture_wrapping::repeat, texture_wrapping::repeat}),
@ -106,7 +117,7 @@ texture_2d::texture_2d(int width, int height, ::pixel_type type, ::pixel_format
max_anisotropy(0.0f) max_anisotropy(0.0f)
{ {
glGenTextures(1, &gl_texture_id); glGenTextures(1, &gl_texture_id);
resize(width, height, type, format, data);
resize(width, height, type, format, color_space, data);
set_wrapping(std::get<0>(wrapping), std::get<1>(wrapping)); set_wrapping(std::get<0>(wrapping), std::get<1>(wrapping));
set_filters(std::get<0>(filters), std::get<1>(filters)); set_filters(std::get<0>(filters), std::get<1>(filters));
set_max_anisotropy(max_anisotropy); set_max_anisotropy(max_anisotropy);
@ -117,13 +128,23 @@ texture_2d::~texture_2d()
glDeleteTextures(1, &gl_texture_id); glDeleteTextures(1, &gl_texture_id);
} }
void texture_2d::resize(int width, int height, ::pixel_type type, ::pixel_format format, const void* data)
void texture_2d::resize(int width, int height, ::pixel_type type, ::pixel_format format, ::color_space color_space, const void* data)
{ {
dimensions = {width, height}; dimensions = {width, height};
pixel_type = type; pixel_type = type;
pixel_format = format; pixel_format = format;
this->color_space = color_space;
GLenum gl_internal_format = internal_format_lut[static_cast<std::size_t>(format)][static_cast<std::size_t>(type)];
GLenum gl_internal_format;
if (color_space == ::color_space::srgb)
{
gl_internal_format = srgb_internal_format_lut[static_cast<std::size_t>(format)][static_cast<std::size_t>(type)];
}
else
{
gl_internal_format = linear_internal_format_lut[static_cast<std::size_t>(format)][static_cast<std::size_t>(type)];
}
GLenum gl_format = pixel_format_lut[static_cast<std::size_t>(format)]; GLenum gl_format = pixel_format_lut[static_cast<std::size_t>(format)];
const GLint* gl_swizzle_mask = swizzle_mask_lut[static_cast<std::size_t>(format)]; const GLint* gl_swizzle_mask = swizzle_mask_lut[static_cast<std::size_t>(format)];

+ 24
- 7
src/rasterizer/texture-2d.hpp View File

@ -20,7 +20,9 @@
#ifndef ANTKEEPER_TEXTURE_2D_HPP #ifndef ANTKEEPER_TEXTURE_2D_HPP
#define ANTKEEPER_TEXTURE_2D_HPP #define ANTKEEPER_TEXTURE_2D_HPP
#include <array>
#include <tuple> #include <tuple>
#include "rasterizer/color-space.hpp"
#include "rasterizer/pixel-format.hpp" #include "rasterizer/pixel-format.hpp"
#include "rasterizer/pixel-type.hpp" #include "rasterizer/pixel-type.hpp"
@ -38,8 +40,12 @@ class texture_2d
public: public:
/** /**
* Creates a 2D texture. * Creates a 2D texture.
*
* @param color_space Specifies the color space of the pixel data.
*
* @warning If the sRGB color space is specified, pixel data will be stored internally as 8 bits per channel, and automatically converted to linear space before reading.
*/ */
texture_2d(int width, int height, ::pixel_type type = ::pixel_type::uint_8, ::pixel_format format = ::pixel_format::rgba, const void* data = nullptr);
texture_2d(int width, int height, ::pixel_type type = ::pixel_type::uint_8, ::pixel_format format = ::pixel_format::rgba, ::color_space color_space = ::color_space::linear, const void* data = nullptr);
/** /**
* Destroys a 2D texture. * Destroys a 2D texture.
@ -48,8 +54,10 @@ public:
/** /**
* Resizes the texture. * Resizes the texture.
*
* @warning If the sRGB color space is specified, pixel data will be stored internally as 8 bits per channel, and automatically converted to linear space before reading.
*/ */
void resize(int width, int height, ::pixel_type type, ::pixel_format format, const void* data);
void resize(int width, int height, ::pixel_type type, ::pixel_format format, ::color_space color_space, const void* data);
/** /**
* Sets the texture wrapping modes. * Sets the texture wrapping modes.
@ -75,13 +83,16 @@ public:
void set_max_anisotropy(float anisotropy); void set_max_anisotropy(float anisotropy);
/// Returns the dimensions of the texture, in pixels. /// Returns the dimensions of the texture, in pixels.
const std::tuple<int, int>& get_dimensions() const;
const std::array<int, 2>& get_dimensions() const;
/// Returns the pixel type enumeration. /// Returns the pixel type enumeration.
const pixel_type& get_pixel_type() const; const pixel_type& get_pixel_type() const;
/// Returns the pixel format enumeration. /// Returns the pixel format enumeration.
const pixel_format& get_pixel_format() const; const pixel_format& get_pixel_format() const;
/// Returns the color space enumeration.
const color_space& get_color_space() const;
/// Returns the wrapping modes of the texture. /// Returns the wrapping modes of the texture.
const std::tuple<texture_wrapping, texture_wrapping> get_wrapping() const; const std::tuple<texture_wrapping, texture_wrapping> get_wrapping() const;
@ -89,7 +100,7 @@ public:
/// Returns the filtering modes of the texture. /// Returns the filtering modes of the texture.
const std::tuple<texture_min_filter, texture_mag_filter> get_filters() const; const std::tuple<texture_min_filter, texture_mag_filter> get_filters() const;
/// Returs the maximum anisotropy.
/// Returns the maximum anisotropy.
float get_max_anisotropy() const; float get_max_anisotropy() const;
private: private:
@ -97,15 +108,16 @@ private:
friend class shader_input; friend class shader_input;
unsigned int gl_texture_id; unsigned int gl_texture_id;
std::tuple<int, int> dimensions;
std::array<int, 2> dimensions;
::pixel_type pixel_type; ::pixel_type pixel_type;
::pixel_format pixel_format; ::pixel_format pixel_format;
::color_space color_space;
std::tuple<texture_wrapping, texture_wrapping> wrapping; std::tuple<texture_wrapping, texture_wrapping> wrapping;
std::tuple<texture_min_filter, texture_mag_filter> filters; std::tuple<texture_min_filter, texture_mag_filter> filters;
float max_anisotropy; float max_anisotropy;
}; };
inline const std::tuple<int, int>& texture_2d::get_dimensions() const
inline const std::array<int, 2>& texture_2d::get_dimensions() const
{ {
return dimensions; return dimensions;
} }
@ -114,12 +126,17 @@ inline const pixel_type& texture_2d::get_pixel_type() const
{ {
return pixel_type; return pixel_type;
} }
inline const pixel_format& texture_2d::get_pixel_format() const inline const pixel_format& texture_2d::get_pixel_format() const
{ {
return pixel_format; return pixel_format;
} }
inline const color_space& texture_2d::get_color_space() const
{
return color_space;
}
inline const std::tuple<texture_wrapping, texture_wrapping> texture_2d::get_wrapping() const inline const std::tuple<texture_wrapping, texture_wrapping> texture_2d::get_wrapping() const
{ {
return wrapping; return wrapping;

+ 9
- 2
src/renderer/passes/material-pass.cpp View File

@ -57,6 +57,7 @@ material_pass::material_pass(::rasterizer* rasterizer, const ::framebuffer* fram
render_pass(rasterizer, framebuffer), render_pass(rasterizer, framebuffer),
fallback_material(nullptr), fallback_material(nullptr),
time_tween(nullptr), time_tween(nullptr),
mouse_position({0.0f, 0.0f}),
focal_point_tween(nullptr), focal_point_tween(nullptr),
shadow_map_pass(nullptr), shadow_map_pass(nullptr),
shadow_map(nullptr) shadow_map(nullptr)
@ -415,6 +416,8 @@ void material_pass::render(render_context* context) const
// Upload context-dependent shader parameters // Upload context-dependent shader parameters
if (parameters->time) if (parameters->time)
parameters->time->upload(time); parameters->time->upload(time);
if (parameters->mouse)
parameters->mouse->upload(mouse_position);
if (parameters->resolution) if (parameters->resolution)
parameters->resolution->upload(resolution); parameters->resolution->upload(resolution);
if (parameters->view) if (parameters->view)
@ -513,6 +516,7 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const shad
// Connect inputs // Connect inputs
parameters->time = program->get_input("time"); parameters->time = program->get_input("time");
parameters->mouse = program->get_input("mouse");
parameters->resolution = program->get_input("resolution"); parameters->resolution = program->get_input("resolution");
parameters->model = program->get_input("model"); parameters->model = program->get_input("model");
parameters->view = program->get_input("view"); parameters->view = program->get_input("view");
@ -548,6 +552,11 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const shad
return parameters; return parameters;
} }
void material_pass::handle_event(const mouse_moved_event& event)
{
mouse_position = {static_cast<float>(event.x), static_cast<float>(event.y)};
}
bool operation_compare(const render_operation& a, const render_operation& b) bool operation_compare(const render_operation& a, const render_operation& b)
{ {
if (!a.material) if (!a.material)
@ -555,8 +564,6 @@ bool operation_compare(const render_operation& a, const render_operation& b)
else if (!b.material) else if (!b.material)
return true; return true;
bool xray_a = a.material->get_flags() & MATERIAL_FLAG_X_RAY; bool xray_a = a.material->get_flags() & MATERIAL_FLAG_X_RAY;
bool xray_b = b.material->get_flags() & MATERIAL_FLAG_X_RAY; bool xray_b = b.material->get_flags() & MATERIAL_FLAG_X_RAY;

+ 8
- 1
src/renderer/passes/material-pass.hpp View File

@ -24,6 +24,8 @@
#include "renderer/material.hpp" #include "renderer/material.hpp"
#include "animation/tween.hpp" #include "animation/tween.hpp"
#include "utility/fundamental-types.hpp" #include "utility/fundamental-types.hpp"
#include "event/event-handler.hpp"
#include "event/input-events.hpp"
#include <unordered_map> #include <unordered_map>
class camera; class camera;
@ -36,7 +38,8 @@ class shadow_map_pass;
/** /**
* Renders scene objects using their material-specified shaders and properties. * Renders scene objects using their material-specified shaders and properties.
*/ */
class material_pass: public render_pass
class material_pass: public render_pass,
public event_handler<mouse_moved_event>
{ {
public: public:
material_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, resource_manager* resource_manager); material_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, resource_manager* resource_manager);
@ -55,12 +58,15 @@ public:
const texture_2d* shadow_map; const texture_2d* shadow_map;
private: private:
virtual void handle_event(const mouse_moved_event& event);
/** /**
* Sets of known shader input parameters. Each time a new shader is encountered, a parameter set will be created and its inputs connected to the shader program. A null input indiciates that the shader doesn't have that parameter. * Sets of known shader input parameters. Each time a new shader is encountered, a parameter set will be created and its inputs connected to the shader program. A null input indiciates that the shader doesn't have that parameter.
*/ */
struct parameter_set struct parameter_set
{ {
const shader_input* time; const shader_input* time;
const shader_input* mouse;
const shader_input* resolution; const shader_input* resolution;
const shader_input* model; const shader_input* model;
const shader_input* view; const shader_input* view;
@ -99,6 +105,7 @@ private:
mutable std::unordered_map<const shader_program*, parameter_set*> parameter_sets; mutable std::unordered_map<const shader_program*, parameter_set*> parameter_sets;
const material* fallback_material; const material* fallback_material;
const tween<double>* time_tween; const tween<double>* time_tween;
float2 mouse_position;
const tween<float3>* focal_point_tween; const tween<float3>* focal_point_tween;
texture_2d* soft_shadows_texture; texture_2d* soft_shadows_texture;

+ 4
- 1
src/resources/texture-2d-loader.cpp View File

@ -58,9 +58,12 @@ texture_2d* resource_loader::load(resource_manager* resource_manager
delete image; delete image;
throw std::runtime_error(stream.str().c_str()); throw std::runtime_error(stream.str().c_str());
} }
// Assume linear color space
::color_space color_space = ::color_space::linear;
// Create texture // Create texture
texture_2d* texture = new texture_2d(image->get_width(), image->get_height(), type, format, image->get_pixels());
texture_2d* texture = new texture_2d(image->get_width(), image->get_height(), type, format, color_space, image->get_pixels());
// Free loaded image // Free loaded image
delete image; delete image;

Loading…
Cancel
Save