WiP
This commit is contained in:
parent
4be1393295
commit
564cda1345
37 changed files with 92 additions and 125 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 1999-2021 Hartmut Seichter
|
||||
Copyright (c) 1999-2024 Hartmut Seichter
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
26
README.md
26
README.md
|
@ -1,27 +1,19 @@
|
|||
# pixwerx
|
||||
|
||||
pixwerx is an opinionated, academic approach to a 3D graphics engine. It mixes
|
||||
modern and proven methods to build a fast and portable graphics system.
|
||||
pixwerx is a general purpose 3D engine written in C++23 and scriptable with Lua.
|
||||
|
||||
## Design Principles
|
||||
|
||||
Dogfooding: pixwerx is built on the principle of dogfooding. The engine is a
|
||||
full-stack system that tries to implement all necessary functions. The engine
|
||||
editor is just a UI build with the engine.
|
||||
|
||||
Reasonable dependencies: like many engines pixwerx tries to include as much 3rd-party code as possible and implements some of the core systems itself.
|
||||
|
||||
No premature optimization: pixwerx implements only very few systems with machine code. It tries to utilize the power of the compiler as much as possible.
|
||||
|
||||
Computer graphics 101: pixwerx does implement graphics components and systems in a way that makes code portable and not over-parameterized. Usability is
|
||||
achieved through layers on top of the core components.
|
||||
## Principles
|
||||
|
||||
- datadriven design
|
||||
- multiple platform capable through heavy usage of STL
|
||||
- minimal set of dependencies
|
||||
- efficiency through meta-meta programming techniques
|
||||
- no CPU intrinsics
|
||||
|
||||
## License
|
||||
|
||||
pixwerx is licenced under the terms of the MIT License. Please consult the
|
||||
LICENSE file.
|
||||
pixwerx is licenced under the terms of the MIT License. Please consult the LICENSE file.
|
||||
|
||||
## Authors
|
||||
|
||||
© 1999-2020 Hartmut Seichter
|
||||
© 1999-2024 Hartmut Seichter
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef PW_CORE_BUFFER_HPP
|
||||
#define PW_CORE_BUFFER_HPP
|
||||
|
||||
#include <pw/core/globals.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // PW_CORE_BUFFER_HPP
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -259,7 +259,7 @@ constexpr auto operator*(const matrix<ScalarA, Ra, Ca>& A,
|
|||
}
|
||||
|
||||
//
|
||||
// matrix aliases
|
||||
// type aliases
|
||||
//
|
||||
|
||||
template <typename Scalar> using matrix2x2 = matrix<Scalar, 2, 2>;
|
||||
|
@ -277,7 +277,7 @@ using matrix4x4d = matrix4x4<double>;
|
|||
} // namespace pw
|
||||
|
||||
//
|
||||
// tuple - protocol
|
||||
// tuple protocol
|
||||
//
|
||||
template <class Scalar, std::size_t R, std::size_t C>
|
||||
struct std::tuple_size<pw::matrix<Scalar, R, C>>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -31,7 +31,7 @@ namespace pw {
|
|||
template <typename Scalar> struct size {
|
||||
|
||||
using value_type = Scalar;
|
||||
Scalar width, height;
|
||||
Scalar width{}, height{};
|
||||
|
||||
constexpr auto area() const noexcept -> Scalar {
|
||||
if constexpr (std::is_unsigned_v<Scalar>) {
|
||||
|
@ -53,7 +53,9 @@ template <typename Scalar> struct size {
|
|||
}
|
||||
};
|
||||
|
||||
// deduction guide for size
|
||||
//
|
||||
// deduction guide
|
||||
//
|
||||
template <class... U, class CT = std::common_type_t<U...>>
|
||||
size(U...) -> size<CT>;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -8,8 +8,8 @@
|
|||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
@ -32,14 +32,13 @@ namespace pw {
|
|||
/**
|
||||
* @brief A simple high resolution timer
|
||||
*/
|
||||
class time {
|
||||
public:
|
||||
struct time final {
|
||||
|
||||
using tick_t = std::chrono::time_point<std::chrono::high_resolution_clock> ;
|
||||
using tick_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
||||
|
||||
time() = default;
|
||||
time() = default;
|
||||
time(const time&) = default;
|
||||
~time() = default; /// d'tor
|
||||
~time() = default; /// d'tor
|
||||
|
||||
/**
|
||||
* @brief reset timer to current system time
|
||||
|
@ -58,12 +57,10 @@ public:
|
|||
*/
|
||||
static double now();
|
||||
|
||||
protected:
|
||||
|
||||
tick_t _start = std::chrono::high_resolution_clock::now();
|
||||
protected:
|
||||
tick_t _start{std::chrono::high_resolution_clock::now()};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -292,14 +292,15 @@ template <typename Scalar, std::size_t N> struct vector final {
|
|||
constexpr const_pointer end() const { return &v_[N]; }
|
||||
};
|
||||
|
||||
// deduction guide for vector
|
||||
//
|
||||
// deduction guide
|
||||
//
|
||||
template <class T, class... U, class CT = std::common_type_t<T, U...>>
|
||||
vector(T, U...) -> vector<CT, 1 + sizeof...(U)>;
|
||||
|
||||
//
|
||||
// Vector Aliases
|
||||
// type aliases
|
||||
//
|
||||
|
||||
template <typename Scalar> using vector2 = vector<Scalar, 2>;
|
||||
template <typename Scalar> using vector3 = vector<Scalar, 3>;
|
||||
template <typename Scalar> using vector4 = vector<Scalar, 4>;
|
||||
|
@ -319,7 +320,7 @@ using vector4i = vector4<int>;
|
|||
} // namespace pw
|
||||
|
||||
//
|
||||
// tuple - protocol
|
||||
// tuple protocol
|
||||
//
|
||||
template <class Scalar, std::size_t N>
|
||||
struct std::tuple_size<pw::vector<Scalar, N>>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -42,4 +42,3 @@ double time::now()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -8,8 +8,8 @@
|
|||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
@ -28,27 +28,22 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
class image_io {
|
||||
public:
|
||||
|
||||
struct image_io final {
|
||||
static image_io& get();
|
||||
|
||||
image read(std::string const& uri,uint32_t flags = 0);
|
||||
image read(std::string const& uri, uint32_t flags = 0);
|
||||
|
||||
bool write(const std::string &uri, const image &img, uint32_t flags = 0);
|
||||
bool write(const std::string& uri, const image& img, uint32_t flags = 0);
|
||||
|
||||
~image_io();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
protected:
|
||||
struct impl;
|
||||
std::unique_ptr<impl> _impl;
|
||||
|
||||
image_io();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||
* Copyright (C) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -32,17 +32,15 @@
|
|||
namespace pw {
|
||||
|
||||
struct camera {
|
||||
matrix4x4 view = matrix4x4::identity();
|
||||
matrix4x4 projection = matrix_transform<float>::look_at(vector3{0,0,0},
|
||||
vector3{0,0,1},
|
||||
vector3{0,1,0});
|
||||
matrix4x4f projection = matrix4x4f::identity();
|
||||
matrix4x4f view = matrix_transform<float>::look_at(vector3f{}, vector3f::x_axis(),
|
||||
vector3f::y_axis());
|
||||
|
||||
rectangle viewport = pw::rectangle({0, 0, 1, 1});
|
||||
matrix4x4f viewport = pw::rectangle{{0.f, 0.f} {1.f, 1.f}};
|
||||
|
||||
uint32_t mask = 0xFFFFFF;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||
* Copyright (C) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -73,4 +73,3 @@ struct projection {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||
* Copyright (C) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2020 Hartmut Seichter
|
||||
* Copyright (C) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1999-2017 Hartmut Seichter
|
||||
* Copyright (C) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
struct input {
|
||||
struct input final {
|
||||
|
||||
static input& get();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -8,8 +8,8 @@
|
|||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
@ -27,38 +27,33 @@
|
|||
|
||||
namespace pw {
|
||||
|
||||
|
||||
class path {
|
||||
public:
|
||||
|
||||
struct path final {
|
||||
using path_list = std::vector<std::string>;
|
||||
|
||||
static path& get();
|
||||
~path();
|
||||
static path& get();
|
||||
~path();
|
||||
|
||||
std::string separator() const;
|
||||
std::string separator() const;
|
||||
|
||||
std::string executable_path() const;
|
||||
std::string executable_path() const;
|
||||
|
||||
path_list resource_paths() const { return _resource_paths; }
|
||||
path_list resource_paths() const { return _resource_paths; }
|
||||
void set_resource_paths(path_list pl);
|
||||
|
||||
std::string find_file(const std::string &filename) const;
|
||||
std::string find_file(const std::string& filename) const;
|
||||
|
||||
std::string get_filename(const std::string &filepath, bool with_extension = true) const;
|
||||
std::string get_filename(const std::string& filepath,
|
||||
bool with_extension = true) const;
|
||||
|
||||
protected:
|
||||
|
||||
path_list _resource_paths;
|
||||
|
||||
path();
|
||||
|
||||
struct impl;
|
||||
std::unique_ptr<impl> _impl;
|
||||
private:
|
||||
path_list _resource_paths;
|
||||
|
||||
path();
|
||||
|
||||
struct impl;
|
||||
std::unique_ptr<impl> _impl;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2021 Hartmut Seichter
|
||||
* Copyright (c) 1999-2024 Hartmut Seichter
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue