|
Aw Donnie,
I was gonna post. In some strange way, it was a relief I was not first, here.
Fare thee well
Adam
PS
I was always more interested in directors than actors. Still I precisely remember the first film I noticed him as an actor:
Eye of the Needle (1981)
PPS
I also recall the first moment I noticed Kiefer Surherland. The opening scene of Flatliners (199x)
“This is a great day to die on.”
"If we don't change direction, we'll end up where we're going"
|
|
|
|
|
I'm not a big baseball fan, although I used to be but this man was a legend, he will be remembered and missed.
Baseball legend Willie Mays dies at 93 | AP News[^]
If you can't find time to do it right the first time, how are you going to find time to do it again?
PartsBin an Electronics Part Organizer - Release Version 1.4.0 (Many new features) JaxCoder.com
Latest Article: EventAggregator
|
|
|
|
|
One of the greatest.
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment
"Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst
"I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle
|
|
|
|
|
say hey.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
One of the key features of my graphics library is the ability to create arbitrary pixel formats so you can for example, create a bitmap with any kind of color model and memory footprint you like.
I thought I was a bit crazy, because most IoT devices are 16-bit RGB if not monochrome.
I thought I was overengineering
Then along came color e-ink and all of the sudden even my palette support made sense.
Then I started doing professional displays on embedded outside the IoT realm and many are 24-bit color.
using rgb24 = gfx::rgb_pixel<24>;
And Bob's your uncle
Well then I made an Arduino emulator for the PC, and directx threw me for a bit of a loop because there are 4 channels but one is unused:
template<size_t BitDepth>
using bgrx_pixel = gfx::pixel<
gfx::channel_traits<gfx::channel_name::B,(BitDepth/4)>,
gfx::channel_traits<gfx::channel_name::G,((BitDepth/4)+(BitDepth%4))>,
gfx::channel_traits<gfx::channel_name::R,(BitDepth/4)>,
gfx::channel_traits<gfx::channel_name::nop,(BitDepth/4),0,(1<<(BitDepth/4))-1,(1<<(BitDepth/4))-1>
>;
using screen_t = uix::screen<bgrx_pixel<32>>;
Bam!
I have not redesigned this feature of my library since its inception in like 2021. It keeps just kicking ass.
I do not design with any expectation that what I designed will remain unchanged that far out because it's usually not realistic. I am not that smart. This was all luck.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
modified 20-Jun-24 7:03am.
|
|
|
|
|
honey the codewitch wrote: I am not that smart. This was all luck.
It's not a coincidence that luck always prefers smart people.
|
|
|
|
|
There's a saying "You make your own luck".
|
|
|
|
|
Napoleon's usual Q at promotion time for an officer: "is he lucky?"
|
|
|
|
|
There's a Swedish former ski-star that, among others, had a saying:
"The more I prepare and train, the more luck I get" Stefan Stenmark, my translation.
Cheers
|
|
|
|
|
You really shouldn't denigrate yourself. You are definitely one of the smart ones on this site.
Bond
Keep all things as simple as possible, but no simpler. -said someone, somewhere
|
|
|
|
|
Oh, I simply meant that I'm not smart enough to think into the future several years out and design ahead. That was luck, is what I'm saying.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
I mean this next statement as a compliment, not a dig.
I think you are confusing "engineering" with "overengineering". "Overengineering" would have been adding n-dimensional planes to cover you when holographic (and imagined 4+D graphics were in vogue).
Seems you like you made a sound design decision that may have felt too liberal because perhaps you had seen one too many poorly designed graphics implementations. Probably why you went to the trouble of writing your own to begin with.
Been a long time since I looked at DirectX, but typically Windows (and quite a few other platforms) use a RGBA model where often you see 8 bits for each (the 'A' is an Alpha channel which is an opacity value). Color models are like opinions ... everyone has one
I haven't looked at your library, but from your example you might be able to use variadic templates to make your 'pixel' definition a bit easier. Or perhaps that would just put you on the path to true overengineering
Keep up the good work.
Cheers,
DL
|
|
|
|
|
Thanks. I mean in hindsight, I agree because I used the stuff I engineered for.
Edit: As far as directx, that's true, except for the format used for the last mile native draw surface. the alpha channel is not used in that situation.
I actually do use variadic templates to do my template definitions.
(background docs if you're interested: https://honeythecodewitch.com/gfx/wiki/pixels.md[^])
Each pixel has one or more channel_traits that are fed into it using variadic templates.
Like so:
template<size_t BitDepth>
using rgb_pixel = pixel<
channel_traits<channel_name::R,(BitDepth/3)>,
channel_traits<channel_name::G,((BitDepth/3)+(BitDepth%3))>,
channel_traits<channel_name::B,(BitDepth/3)>
>;
template<size_t BitDepth>
using rgba_pixel = pixel<
channel_traits<channel_name::R,(BitDepth/4)>,
channel_traits<channel_name::G,((BitDepth/4)+(BitDepth%4))>,
channel_traits<channel_name::B,(BitDepth/4)>,
channel_traits<channel_name::A,(BitDepth/4),0,(1<<(BitDepth/4))-1,(1<<(BitDepth/4))-1>
>;
template<size_t BitDepth>
using gsc_pixel = pixel<
channel_traits<channel_name::L,BitDepth>
>;
template<size_t BitDepth>
using yuv_pixel = pixel<
channel_traits<channel_name::Y,((BitDepth/3)+(BitDepth%3))>,
channel_traits<channel_name::U,(BitDepth/3)>,
channel_traits<channel_name::V,(BitDepth/3)>
>;
template<size_t BitDepth>
using yuva_pixel = pixel<
channel_traits<channel_name::Y,((BitDepth/4)+(BitDepth%4))>,
channel_traits<channel_name::U,(BitDepth/4)>,
channel_traits<channel_name::V,(BitDepth/4)>,
channel_traits<channel_name::A,(BitDepth/4),0,(1<<(BitDepth/4))-1,(1<<(BitDepth/4))-1>
>;
And here's the actual pixel class.
template<typename... ChannelTraits>
struct pixel {
using type = pixel<ChannelTraits...>;
using rgb_conversion_type = pixel<channel_traits<channel_name::R,16>,channel_traits<channel_name::G,16>,channel_traits<channel_name::B,16>,channel_traits<channel_name::A,16>>;
using int_type = bits::uintx<bits::get_word_size(helpers::bit_depth<ChannelTraits...>::value)>;
constexpr static const size_t channels = sizeof...(ChannelTraits);
constexpr static const size_t color_channels = helpers::color_channels_size<ChannelTraits...>::value;
constexpr static const size_t bit_depth = helpers::bit_depth<ChannelTraits...>::value;
constexpr static const size_t packed_size = (bit_depth+7) / 8;
constexpr static const bool byte_aligned = 0==bit_depth/8.0 - (size_t)(bit_depth/8);
constexpr static const size_t total_size_bits = sizeof(int_type)*8;
constexpr static const size_t packed_size_bits = packed_size*8;
constexpr static const size_t pad_right_bits = total_size_bits-bit_depth;
constexpr static const int_type mask = int_type(int_type(~int_type(0))<<(pad_right_bits));
int_type native_value;
constexpr inline pixel() : native_value(0) {
helpers::pixel_init_impl<type,0,ChannelTraits...>::init(*this);
}
constexpr inline pixel(int_type native_value,bool dummy) : native_value(native_value) {
}
constexpr inline pixel(typename ChannelTraits::int_type... values) : native_value(0) {
helpers::pixel_init_impl<type,0,ChannelTraits...>::init(*this,values...);
}
constexpr inline pixel(bool dummy,typename ChannelTraits::real_type... values) : native_value(0) {
helpers::pixel_init_impl<type,0,ChannelTraits...>::initf(*this,values...);
}
constexpr inline int_type value() const {
return helpers::order_guard(native_value);
}
constexpr inline void value(int_type value) {
native_value=helpers::order_guard(value);
}
constexpr inline bool operator==(pixel rhs) {
return rhs.native_value==native_value;
}
constexpr inline bool operator!=(pixel rhs) {
return rhs.native_value!=native_value;
}
template<int Index> using channel_by_index = typename helpers::channel_by_index_impl<type,Index,channels,0,ChannelTraits...>::type;
template<int Index> using channel_by_index_unchecked = typename helpers::channel_by_index_unchecked_impl<type,Index,channels,0,ChannelTraits...>::type;
template<typename Name> using channel_index_by_name = typename helpers::channel_index_by_name_impl<0,Name,ChannelTraits...>;
template<typename Name> using channel_by_name = channel_by_index<helpers::channel_index_by_name_impl<0,Name,ChannelTraits...>::value>;
template<typename Name> using channel_by_name_unchecked = channel_by_index_unchecked<channel_index_by_name<Name>::value>;
template<typename... ChannelNames> using has_channel_names = typename helpers::has_channel_names_impl<type,ChannelNames...>;
template<typename... ChannelNames> using is_color_model = typename helpers::is_color_model_impl<type,ChannelNames...>;
template<typename PixelRhs> using is_subset_of = typename helpers::is_subset_pixel_impl<PixelRhs,ChannelTraits...>;
template<typename PixelRhs> using is_superset_of = typename PixelRhs::template is_subset_of<type>;
template<typename PixelRhs> using unordered_equals = typename helpers::unordered_equals_pixel_impl<type,PixelRhs>;
template<typename PixelRhs> using equals = typename helpers::equals_pixel_impl<PixelRhs,ChannelTraits...>;
template<typename PixelRhs> using equals_exact = typename helpers::is_same<type,PixelRhs>;
template<int Index>
constexpr inline typename channel_by_index_unchecked<Index>::int_type channel_unchecked() const {
return helpers::get_channel_direct_unchecked<type,Index>(native_value);
}
template<int Index>
constexpr inline void channel_unchecked(typename channel_by_index_unchecked<Index>::int_type value) {
helpers::set_channel_direct_unchecked<type,Index>(native_value,value);
}
template<int Index>
constexpr inline typename channel_by_index<Index>::int_type channel() const {
using ch = channel_by_index<Index>;
return typename ch::int_type(typename ch::pixel_type::int_type(native_value & ch::channel_mask)>>ch::total_bits_to_right);
}
template<int Index>
constexpr inline void channel(typename channel_by_index<Index>::int_type value) {
using ch = channel_by_index<Index>;
const typename ch::pixel_type::int_type shval = typename ch::pixel_type::int_type(typename ch::pixel_type::int_type(helpers::clamp(value,ch::min,ch::max))<<ch::total_bits_to_right);
native_value=typename ch::pixel_type::int_type((native_value&typename ch::pixel_type::int_type(~ch::channel_mask))|shval);
}
template<int Index>
constexpr inline typename channel_by_index_unchecked<Index>::real_type channelr() const {
using ch = channel_by_index<Index>;
return channel<Index>()*ch::scaler;
}
template<int Index>
constexpr inline void channelr(typename channel_by_index<Index>::real_type value) {
using ch = channel_by_index<Index>;
channel<Index>(value*ch::scale+.5);
}
template<int Index>
constexpr inline typename channel_by_index_unchecked<Index>::real_type channelr_unchecked() const {
using ch = channel_by_index_unchecked<Index>;
return (typename ch::real_type)channel_unchecked<Index>()*ch::scaler;
}
template<int Index>
constexpr inline void channelr_unchecked(typename channel_by_index<Index>::real_type value) {
using ch = channel_by_index_unchecked<Index>;
channel_unchecked<Index>(value*ch::scale+.5);
}
template<typename Name>
constexpr inline auto channel() const {
const int index = channel_index_by_name<Name>::value;
return channel<index>();
}
template<typename Name>
constexpr inline void channel(typename channel_by_index<channel_index_by_name<Name>::value>::int_type value) {
const int index = channel_index_by_name<Name>::value;
channel<index>(value);
}
template<typename Name>
constexpr inline auto channelr() const {
const int index = channel_index_by_name<Name>::value;
return channelr<index>();
}
template<typename Name>
constexpr inline void channelr(typename channel_by_name<Name>::real_type value) {
const int index = channel_index_by_name<Name>::value;
channelr<index>(value);
}
constexpr double difference(type rhs) const {
return sqrt(helpers::pixel_diff_impl<type,0,ChannelTraits...>::diff_sum(*this,rhs));
}
constexpr gfx_result blend(const type rhs,double ratio,type* out_pixel) const {
if(out_pixel==nullptr) {
return gfx_result::invalid_argument;
}
static_assert(!has_channel_names<channel_name::index>::value,"pixel must not be indexed");
if(ratio==1.0) {
out_pixel->native_value = native_value;
return gfx_result::success;
} else if(ratio==0.0) {
out_pixel->native_value = rhs.native_value;
return gfx_result::success;
}
if(type::template has_channel_names<channel_name::A>::value) {
constexpr const int ai = type::channel_index_by_name<channel_name::A>::value;
float a1 = this->template channelr_unchecked<ai>();
float a2 = rhs.template channelr_unchecked<ai>();
float r2 = a1/a2;
ratio = ratio * r2;
if(ratio>1.0)
ratio = 1.0;
}
helpers::pixel_blend_impl<type,0,ChannelTraits...>::blend_val(*this,rhs,ratio,out_pixel);
return gfx_result::success;
}
constexpr type blend(const type rhs,double ratio) const {
type result;
blend(rhs,ratio,&result);
return result;
}
static_assert(sizeof...(ChannelTraits)>0,"A pixel must have at least one channel trait");
static_assert(bit_depth<=HTCW_MAX_WORD,"Bit depth must be less than or equal to the maximum machine word size");
};
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
I hate to do the "Cat video" thing, but technology is involved, and Robot Vacuum Pushes Cat Under Couch[^]
That's one patient cat - Dij would never have put up with such insolence!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
That's because AI knows better... The robot learned that that part of the house is a floor and must be cleand!
"It never ceases to amaze me that a spacecraft launched in 1977 can be fixed remotely from Earth." ― Brian Cox
|
|
|
|
|
|
Ok. That was cute, even though it was about cats.
Within you lies the power for good - Use it!
|
|
|
|
|
Professor Brian Cox[^]
That last sentence sums up the majority of people on t'interwebs (this site excluded, natch*).
* The regulars** anyway.
** Well, most of 'em.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
The paradox exists becasue we are part of the problem and believe to be part of the solution...
"It never ceases to amaze me that a spacecraft launched in 1977 can be fixed remotely from Earth." ― Brian Cox
|
|
|
|
|
We get some wanderers from time to time.
|
|
|
|
|
I thought you didn't do Twatter.
This fact may, or may not, have something to do with the Fermi paradox.
|
|
|
|
|
I don't. But I do know deluded fools who do.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I guess that depends on the meaning of "do"
For example, I do not have an active twitter account. However, tweets find me through other avenues online, even on codeproject, as above. Sometimes I'll share them if they're funny or otherwise amusing. I can't log on to the platform formerly known as X and I have no intention of changing that. Perhaps that's the case with Griff.
Check out my IoT graphics library here:
https://honeythecodewitch.com/gfx
And my IoT UI/User Experience library here:
https://honeythecodewitch.com/uix
|
|
|
|
|
Pretty much the same - I don't have a Twatter / Echh account and never have but twaats find their way too me sometimes.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I will lean on the side that all life seeks self survival, and so large collections are difficult to maintained. Selfishness limits a upper limit.
|
|
|
|
|