#Fwog and co.

1 messages Β· Page 18 of 1

golden schooner
#

from polyhaven

#

the blue orange pink purple thing is mine and the red sky stuff i dont rember where i got hat from

fiery sorrel
#

thank you! I can save all of these just for my own uses too :)

long robin
hollow crystal
#

I just use a long y texture strip for cubemaps

#

Wonder if other layouts are better

golden schooner
fiery sorrel
#

I have it toggleable too

#

so on the page it can show both. Off by default :D

#

now I can backport it to Alberquerque as a template lol

long robin
#

how tf did deccer manage to build deccer in 1 hour

#

it's taking half that long to just download deps

#

now it's been compiling for 15 minutes with no sign of slowing down

#

it finally finished with apparently no errors

#

oh that was just the deps bleakekw

#

blender puts the build files in the parent folder of the git root directory bleakekw

fiery sorrel
long robin
fiery sorrel
#

i have no idea what that is

long robin
#

I'm building blender

fiery sorrel
#

ooh

long robin
#

it's very "and co."-related

fiery sorrel
#

I forgot to delete the Deccer Cube models in Fwog Cmake Template so imma do that

long robin
#

Once opened it's very important the following steps are taken:

In the solution explorer find the INSTALL project, right click it and select 'Build' this will copy all the required files the the blender output folder. NOTE: This needs to be done atleast once for every solution configuration, ie: if you switch from Debug to Release configuration you need to redo this step.

#

where

#

ah, it's in CMakePredefinedTargets

#

was pretty easy to build, just took a while

#

didn't have to change my python install or anything πŸ˜‰

long robin
#

idk where they load gltf though

#

wtf this version of blender doesn't even have gltf support

fiery sorrel
#

wtf

long robin
#

blender 4.0.0 alpha

#

why is the gltf gone

long robin
#

I made a post in the blender discord begging for help, so we'll see

daring surge
#

oh god a big discord

#

good luck

long robin
#

Barely anyone posts in the coding channel so eh

daring surge
#

maybe theres an irc if you had no luck?

long robin
#

Nano seems to post there, so I pray he sees

#

Yeah the official modes of communication aren't even discord

#

But I don't want to sign up for a discourse account or whatever (yet)

golden schooner
#

the gltf is a separate plugin as i mentioned in my #1019740157798273024 message

#

building blender was total waste of time πŸ˜›

#

albeit a not a unpleasant experience

#

with having to install this and that and config this and that first

long robin
#

ah

#

I should've read that

#

python 😩

golden schooner
#

: )

#

the plugins also has tons of weird comments πŸ˜„ but im not complaining about it

#

made by volunteers

long robin
#

how might I go about invoking gltfpack from python in a platform-agnostic way, I wonder

fiery sorrel
long robin
#

I could just ship windows and linux binaries, then conditionally call those with subprocess.run 😳

fiery sorrel
#

but i dont wanna do Deccers Cube (Fwog Version) rn because I gotta plan out the architecture if I wanna do it without using that SceneManager example and wanting to do it blind with either fastgltf or cgltf or tinygltf

#

altho i guess i can try a naive one since all I need is the vertices and transforms

#

actually thats a good suggestion. I was already thinking of a separate Project example in the Fwog Template that refactors the structs into classes (and hence separate cpp and h files) (I kept it in same .h file to keep it 'in the spirit' of the Fwog Examples originally and will keep that as a defualt example)

#

but now I can also have Deccer Cube inside there too good point

long robin
#

hmm I'm too much of a python noob to do this properly

#

I don't know the correct way to ship a python script that needs to invoke another executable that it also shipped with

long robin
#

using python to parse gltf πŸ’€

#

it's no surprise that it takes like 2 minutes to import the bistro

golden schooner
#

and i was also wondering that you can have some of the gltfpack options show up as checkboxes

#

which influence the params of the process call then

long robin
#

that's exactly what I wanted to do

golden schooner
#

same here πŸ™‚

long robin
#

except I dunno how to package gltfpack

heavy cipher
golden schooner
#

is gltfpack part of the vulkansdk by any chance?

#

or some other "pack" one can "install"

long robin
golden schooner
#

otherwise, perhaps have a config file or blender setting somehoe where you specify the gltfpack path

heavy cipher
#

hmm i'd think deccer is multilingual enough to stand in for peter

long robin
golden schooner
#

that peter thing is currently flying over my head

long robin
#

ah, that's unrelated to the joke (which I do not get) KEKW

golden schooner
#

ah

#

ah fucking family guy

#

ill be back in ~5ish hours

dapper gorge
golden schooner
#

meshopt is part of gltfpack i sink

heavy cipher
#

deccer doin a brb to learn the language

dapper gorge
#

they are one and the sameℒ️

golden schooner
#

: P

#

jaker go to bed

long robin
#

I would if I didn't have to explain that peter thing

golden schooner
#

πŸ˜„

long robin
#

but now I'm forced to learn how to ship gltfpack with a python script (how)

heavy cipher
dapper gorge
long robin
#

you know, I'd actually rather rewrite the whole thing to just call fastgltf or something

#

so it's not so painfully slow

dapper gorge
#

it likely doesn't matter

long robin
#

but for now I just want to invoke gltfpack to make my life easier

dapper gorge
#

all the python CPU overhead will be far more anyways

long robin
#

well if the entire import function just invoked someOtherProcess.exe -import, the overhead shouldn't be too bad

fiery sorrel
#

what was martty's canon event

golden schooner
golden schooner
heavy cipher
#

napoleonic

#

but it is just a legend

golden schooner
#

ah

#

mais, oui πŸ™‚

long robin
#

hon hon

golden schooner
#

yeah

fiery sorrel
long robin
#

this user seems to really enjoy building other people's projects and letting them know if it works or not πŸ˜„

daring surge
#

masochistic

long robin
#

btw, I think I could use a lee diagram to make cooler/more dynamic rainbows/atmospheric effects

#

it's basically a 2D version of the scattering lut I have now, where the x-axis is the size of the suspended water particles

daring surge
#

well

#

isn't it more like you can't instance the right functions because you don't know about usage when compiling that file?

long robin
#

why you replying in here πŸ€”

#

well it's too late now

daring surge
#

because notapenguin is a rust man

long robin
#

lel

daring surge
#

the problem should be that when you compile the .cpp file, you don't know what usages of it there are, i think what you said is correct, but i think it can be misleading

long robin
#

I think what I said is pretty clear

daring surge
#

the reason is that you cannot instantiate a template without seeing its definition
the implication from usages instantiating is not obvious

#

especially for someone new to templates

long robin
#

instantiate = "plug in the template args and generate code for it"

daring surge
#

yes, most functions don't work that way though

#

oh well, maybe i'm just correcting my own way of thinking

long robin
daring surge
long robin
#

I'm talking about template functions though

daring surge
#

i think what you said is correct (...)
oh well, maybe i'm just correcting my own way of thinking
:)

#

i don't naturally think of template usage instantiating code, i could imagine a world where they're not inlined and the usage just asks for a signature

long robin
#

I guess what I'm saying is that writing
someTemplateFunc<Foo>();
may cause a function to be emitted in the binary, if the definition of someTemplateFunc is visible (since non-specialized template funcs are implicitly inline)

#

if the definition of someTemplateFunc isn't visible, then I guess the linker must find it (which means someTemplateFunc<Foo> must have been instantiated elsewhere)

daring surge
#

yes that makes sense (more independently πŸ˜„)

long robin
#

which is why you get linker errors if you define template funcs in cpps and try to call them

long robin
#

anyways, good idea @tired sandal

tired sandal
long robin
#

I'm also considering redoing pipelines and making them more dynamic

#

i.e., providing the graphics pipeline state as a struct instead of a "compiled object" (so you can change stuff if needed)

#

the whole Vulkan saga of moving away from pipelines is making me rethink them as well

final cove
#

from what it sounds like that's more to cater to people (aka legacy ports) who can't into pipelines

#

embrace the pipeline

long robin
#

yeah, that's certainly an aspect

tired sandal
#

so they went full circle bleakekw

long robin
#

Fwog has almost 0 "dynamic state", so anything that requires changing a specific bit between draws will require a bunch of pipelines and binds

golden schooner
#

@tired sandal please setup a proper github pfp, the default ones suck

robust bough
#

@long robin how stable is fwog? I'm thinking of using it

long robin
#

wdym stable

robust bough
#

how often will the API break

long robin
#

frequently

#

but the breaks should be manageable

robust bough
#

what's the worst that could happen

#

lets try it

long robin
#

and I'll try to put a bunch of breaking changes into releases/tags

#

so you can stick to one version for as long as possible

robust bough
#

i will just use fetchcontent with tags so everything works nicely

#

time for henlo world

#

oh

#

i need to bring my own glad?

#

do I do core / compat @long robin ?

long robin
#

you don't have to bring glad, but you can

robust bough
#

After you have created a window and OpenGL context (e.g., with GLFW) and loaded OpenGL function pointers (e.g., with Glad)

long robin
#

oh wait

#

yeah you have to bring glad

robust bough
#

lel

long robin
#

thanks docs

robust bough
#

good docs

long robin
#

I should mention in the docs what features are required

robust bough
#

is it not possible to just ship glad?

long robin
#

4.6 core with bindless is the minimum I think

#

hmm

#

I think I'm having dementia

robust bough
#

doing compat should work right?

long robin
#

fwog ships glad, but you need to just call the load function yourself

robust bough
#

oh what

#

i must find this

long robin
#

ye check the examples

#

common/application.cpp

robust bough
#

oh neat

#

now lets see if i remember how to open a window

#

we have window

#

im trying to recreate a game i used to play a long time ago

#

the company made it bad πŸ˜”

#

I have finally bit the bullet, I will now make my own gameℒ️

#

time to get stuck in a hell loop of refactoring

long robin
#

this formatting hurts my soul

tired sandal
long robin
#

yeah

fiery sorrel
#

Lets go Fwog Tanks @robust bough

robust bough
long robin
#

@tired sandal implemented your issue

#

took a moment to convert all the examples πŸ˜„

#

hmm I'll make a tag at the latest commit

wind trout
#

Dang I’ve been away from everything too long

#

Looks like fwog progressed a lot

#

Nice!

long robin
#

hmm I need to make sure the docs are still up-to-date

robust bough
#

triangle!

dapper gorge
#

Now make triangle soup

robust bough
#

now i begin abstracting

#

and adding the GUI

dapper gorge
#

And after that, make triangle soup have pretty colors

robust bough
#

im not entirely sure how im going to do my GUI

#

since before it was based on raw OpenGL, but I think it shouldn't be too bad to translate it

tired sandal
#

When I want to create a Tex2DArray, what is the Z component of Extent3D and numArrayLayers?

#
  struct TextureCreateInfo
  {
    ImageType imageType = {};
    Format format = {};
    Extent3D extent = {};
    uint32_t mipLevels = 0;
    uint32_t arrayLayers = 0;
    SampleCount sampleCount = {};

    bool operator==(const TextureCreateInfo&) const noexcept = default;
  };

Does Extent3D contain the array size or arrayLayers?

#

nvm.
layer is just a really weird term. I guess its because OpenGL calls them this aswell.

heavy cipher
#

2d array images have z=1 and arraylayers > 1 i expect

tired sandal
#

Well, you specifiy the Texture Type anyway, so someone might expect Extent3D.z to be the array size.
A Texture2D is similar to a Texture3D, where Depth determines the Array Size.froge

#

and there is no Texture3DArray

robust bough
#

Is there any documentation on how to use uniforms with fwog?

robust bough
#

got it all working

#

now for camera stuff

rugged notch
#

fun fact I've never used fwog before

robust bough
#

There are reflective triangles, transparent triangles, and emissive triangles (but they're set to have emission of 0)

#

This is to simulate a blind person playing a game

rugged notch
#

impressive, very nice

robust bough
rugged notch
#

now let's see Paul Allen's black window

robust bough
#

its not a black window

#

it's a fully fledged RTGI renderer, made to render as if you were a blind person

golden schooner
brazen glacier
#

seems pretty accurate, coping is definitely involved when you're using opengl

golden schooner
#

heh

tired sandal
#

what am I doing wrong?

#version 450 
layout (location = 0) out vec2 out_uv;
void main() {
    out_uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);
    gl_Position = vec4(out_uv * 2.0f + -1.0f, 0.0f, 1.0f);
}
#version 450
layout(location = 0) in vec2 in_uv;
layout(location = 0) out vec4 out_color;
layout(binding = 0) uniform sampler2D image;
void main() {
    out_color = texture(image,in_uv);
}
Fwog::GraphicsPipelineInfo create_fullscreen_pipeline_info() {
   std::ifstream vs("shaders/fullscreen.vert.glsl");
   std::string vertex_source((std::istreambuf_iterator<char>(vs)),std::istreambuf_iterator<char>());
   auto vertex = Fwog::Shader(Fwog::PipelineStage::VERTEX_SHADER,vertex_source);
   std::ifstream fs("shaders/fullscreen.frag.glsl");
   std::string fragment_source((std::istreambuf_iterator<char>(fs)),std::istreambuf_iterator<char>());
   auto fragment = Fwog::Shader(Fwog::PipelineStage::FRAGMENT_SHADER,fragment_source);
   Fwog::ColorBlendAttachmentState blend_state{};
   auto info = Fwog::GraphicsPipelineInfo{};
   info.name = "fullscreen triangle";
   info.vertexShader = &vertex;
   info.fragmentShader = &fragment;
   info.colorBlendState = Fwog::ColorBlendState{false,{},{&blend_state,1}};
   return info;
}
long robin
#

sry was playing aoe2 when you sent this

#

@tired sandal what does the info log say

heavy cipher
#

smh should've rung the town bell

tired sandal
#

"unknown reason", see left side

long robin
#

ah

#

do the source strings look correct when you load them (i.e., they are what you expect them to be)

#

I can compile and link your shaders fine, so it's probably the loading that's messed up

#

confirm by trying to load these strings

const char* gVertexSource = R"(
#version 450 
layout (location = 0) out vec2 out_uv;
void main() {
    out_uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);
    gl_Position = vec4(out_uv * 2.0f + -1.0f, 0.0f, 1.0f);
}
)";

const char* gFragmentSource = R"(
#version 450
layout(location = 0) in vec2 in_uv;
layout(location = 0) out vec4 out_color;
layout(binding = 0) uniform sampler2D image;
void main() {
    out_color = texture(image,in_uv);
}
)";
tired sandal
#

the construction of Fwog::Shader works

long robin
#

even empty strings compile (for some reason)

long robin
#

huh

tired sandal
#

is this a lifetime issue?

long robin
#

ah

#

yeah

#

the info struct is holding a pointer to the shaders, which die when you return from this function

#

have the function return a graphics pipeline instead of the info for it, and that should resolve the issue

tired sandal
tired sandal
#

works

#

:fwogeheart:

tired sandal
#

@long robin nitpick:
ClearColorValue takes either float[4],int32[4], or whatever T[4].
When you clear a texture you explicitly assert for float[4].

#

I'd convert the values to float when possible (i dont really see a reason to support anything else?)

long robin
#

the reason is to allow clearing uint and int textures

#

I only assert that it's float for rendering to the swapchain methinks

#

and for this (clearing float/norm textures)

          case detail::GlBaseTypeClass::FLOAT:
            FWOG_ASSERT((std::holds_alternative<std::array<float, 4>>(ccv.data)));
            glClearNamedFramebufferfv(context->currentFbo, GL_COLOR, i, std::get_if<std::array<float, 4>>(&ccv.data)->data());
            break;
tired sandal
#

oh yes, you are right

#

nvm then

tired sandal
#

a very fwoggy triangle.
First Rendered to a Texture and then to the Swapchain frogegreenexcited

dapper gorge
#

What will you be doing with our lord and savior Fwog

tired sandal
#

Fwoggy things

#

It's a lot better than plain OpenGl frogeheart

fiery sorrel
# long robin ah

Fwog not having a way to output glsl errors to a logger is something i noticed and thought about making a Issues for

#

But I cant think of an alternative other than compiling shaders potentially allowing it to return the string as an error or allow passing in a callback logger function something

golden schooner
#

thats why i return a std::expected in my pipeline compiler

fiery sorrel
#

Yes i like how Cmake Template does it xD

golden schooner
#

when successful you grab the cooked pipeline, othrwise you can access the error and print and peace out

fiery sorrel
#

Woah std::expected is cool!

#

Its like baby exceptions without performance cost?

dapper gorge
#

You can think of it like that

#

except in a language without pattern matching std::expected is more of a chore to use than actually being useful

fiery sorrel
heavy cipher
#

"performance" "concerns"

golden schooner
rugged notch
#

generally you'd use an expected for stuff like parsing

#

where you have a function that maps some T to some U, but can fail

#

it's a pretty nice way to validate data coming in from the outside for example

#

which handles failure quite nicely

#

especially since failure isn't exceptional in parsers, you might have multiple parsers you try in a row, where if one fails you use the next

#

stuff like that

fiery sorrel
#

Thank u for teaching i did not know this

rugged notch
#

it's not in c++ just yet, but there's lots of libraries for it

#

it's basically just an optional with a T instead of a monostate

#

so it's not too hard to implement

tired sandal
#

expected is in c++ since c++23

rugged notch
#

which is in December, iirc

tired sandal
#

"not in c++ yet" sounds like it doesnt even have a draft.
Its in the standard and some compilers already implemented it

#

but i get what you mean πŸ˜„

rugged notch
#

true, true

#

nah you're right

#

anywhoo it's nice, but as LVSTRI said, it's quite annoying to use without pattern matching

tired sandal
#

same for std::variant or std::any froge_sad

rugged notch
#

or std::optional yeah

#

just kinda sucks

#

better than nothing though

tired sandal
#

how am I supposed to tell Fwog that it should generate a texture with as many mips as possible, when the size isn't known?
Do I need to calc the amount myself or is that done automatically via magic number?

dapper gorge
#

1 + floor(log2(max(w, h)));

fiery sorrel
#

Further explantation for ^

long robin
#

Fwog throws an object containing the info log if compilation or linking fails

long robin
#

Fwog::MAX_LEVELS or something

fiery sorrel
#

oh im just a clown

#

The best part about my clown act is I have a PR on this exact code (fixing the bug where glDeleteShader and glGetShaderInfo order)

#

but because im a clown I always read the infoLog from Visual Studios when the exception is thrown by MSVC and forgot that... i can... catch... exceptions...

#

oh is that why I didn't make the ticket about it... becuase... because it already does throw it...

tired sandal
#

which also means it will storage for mips as a default, which is 99% of cases

long robin
#

I've seen multiple users here get trolled by that behavior already πŸ˜„

#

0 is the same thing, just not as well documented

dapper gorge
#

Explicit > Implicit

long robin
tired sandal
#

Fwog::GenerateAllMips declared as 0xFFFFFFFF bleakekw

tired sandal
#

can we getsome verbose logging? Idk maybe a #define?
Logging that displays the inner workings (basically log constructor/destructor calls, when a framebuffer gets cleared, or rendered...) and reports errors frogeheart

golden schooner
#

ugh

#

id advocate for having spdlog added, if logging is to be added

long robin
#

I could add a logging callback instead of integrating a fat library like spdlog

golden schooner
#

and then use its config properly

#

you could

#

and peeps can add their lib of choice

#

but

long robin
#

spdlog makes me sad because it's a good library that annihilates compile times

golden schooner
#

does it really?

long robin
#

It did in my voxel engine πŸ˜„

#

I think using a callback is better anyways

long robin
#

I realized that it would definitely be more thorough

golden schooner
#

ah glPushDebugMessage

#

logging when fb gets cleared?

heavy cipher
golden schooner
#

whats wrong with it

long robin
#

I guess what I mentioned

#

obliterating compile perf is a bit of a deal breaker in some cases

golden schooner
#

hmm

long robin
#

newer versions have a header with forward declarations, which may help

golden schooner
#

would pch help there as well?

dapper gorge
#

Don't worry guys, modules will come and save the day!

golden schooner
#

modules are as away as fusion power, another 10 years

dapper gorge
#

Fusion Power is still a dream because German, American and Japanese engineers are slacking smh

golden schooner
#

i had hopes that modules are shrimpler than fusion : >

brazen glacier
#

at least when working on nuclear fusion you can easily guarantee the presence of a filesystem

long robin
# tired sandal can we getsome verbose logging? Idk maybe a #define? Logging that displays the ...

here's what I'm thinking

  • recoverable errors (very few of these) are exceptions
  • bugs (failed pre/post-conditions) are checked with asserts
  • other potentially notable things (like when samplers, vertex arrays, and framebuffers are implicitly created) can be logged
    I dunno about logging the construction and destruction of every object though. I suppose it's something I can do if you'd like (and I can see some value in visualizing when you create or destroy API objects)
#

the first two are already implemented

robust bough
#

@long robin is there any documentation on creating my own framebuffer?

long robin
#

framebuffers don't exist

robust bough
#

swapchains?

long robin
#

Fwog::Render accepts a list of render targets

robust bough
#

hm, so how do I create a render target?

long robin
#

ah, they're just textures

robust bough
#

hm? what about depth buffer then?

robust bough
#

so do I just create the textures myself and give them to render info?

long robin
#

yeah

#

I'll show you a code example

robust bough
#

ah ok

#

tanks

#

lets see if I can get this working

long robin
#

insh'allah the fwog will render

robust bough
#

the gui lib i use renders on CPU

#

so I need to upload it to a texture

#

so basically I create a framebuffer to render all the game stuff to, then a texture for the gui

#

then I do fst to blit both (or either) to the final framebuffer

#

hm

#

where's that bufferless fst trick again

#

i can never find it

robust bough
#

πŸ˜” black screen

#
Fwog::GraphicsPipeline tanks::renderer::finalize_render::create_pipeline() {
  auto vertex_shader = Fwog::Shader(Fwog::PipelineStage::VERTEX_SHADER, tanks::read_file(std::string(TANKS_ASSET_PATH) + "/shader/finalize_render/shader.vert"));
  auto fragment_shader = Fwog::Shader(Fwog::PipelineStage::FRAGMENT_SHADER, tanks::read_file(std::string(TANKS_ASSET_PATH) + "/shader/finalize_render/shader.frag"));

  return Fwog::GraphicsPipeline{{
                                  .vertexShader = &vertex_shader,
                                  .fragmentShader = &fragment_shader,
                                  .inputAssemblyState = {.topology = Fwog::PrimitiveTopology::TRIANGLE_LIST},
                                  .vertexInputState = {}
                                }};
}```
#
  Fwog::Cmd::BindGraphicsPipeline(pipelines.finalize_render.instance);
  Fwog::Cmd::Draw(3, 1, 0, 0);```
#

this should be everything I need right?

long robin
#

are you compiling for debug

robust bough
#

yes

long robin
#

ok well you're probably not breaking the API at least

#

try disabling backface culling

robust bough
#

raw opengl call?

long robin
#

no, I'll show

#

I think the full screen tri that I showed is clockwise-wound

#

which is really dumb, considering that the default winding is ccw

robust bough
#

yep

#

that was it

long robin
#

then you won't need to change your pipeline

robust bough
#

@long robin maybe it could be a good idea to create a sort of framebuffer / swapchain abstraction?

#

so you can create a swapchain to render to

long robin
#

hmm

#

you can just save your RenderInfo, no?

#

just make sure it's not holding dangling pointers

robust bough
#

potentially

#

maybe something like

auto swapchain = Fwog::CreateSwapChain({
  .extent = {1920, 1080},
  .capabilities = Fwog::SwapChainCapabilities::Depth,
  .colorFormat = Fwog::Format::<>,
});```
long robin
#

oh is this for the window

robust bough
#

then you could get the default swapchain somehow?

long robin
robust bough
#

hm

long robin
#

opengl sucks, so you can't actually get the swapchain as a texture

robust bough
#

yeah i dont mean getting the texture

long robin
#

that's why I need a special function for rendering to it

#

fwog also doesn't handle window creation

robust bough
#

make it so you can't access the default swapchains texture?

#

yeah this wouldn't create a window

#
    Fwog::RenderToSwapchain(Fwog::Swapchain::Default, [&]{
      renderer.render(view_matrix);
    });```
#

thats how you could render to the default one

robust bough
long robin
#

I think I'm having trouble understanding what this is for

robust bough
#

its not for anything specifically

long robin
#

it maybe seems like you want just one function for rendering

robust bough
#

i dont have a specific use case

#

it's just an idea

long robin
#

instead of split into Render and RenderToSwapchain

long robin
robust bough
#

just create a framebuffer

long robin
#

hmm

#

what would these do under the hood?

  .extent = {1920, 1080},
  .capabilities = Fwog::SwapChainCapabilities::Depth,
  .colorFormat = Fwog::Format::<>,
robust bough
#

extent is just how big it is, capabilities would just be (for example depth). if it's specified, it'll create a depth buffer for the framebuffer to use as well, then color format is just the format of the color texture

long robin
#

oh I see

#

when I say Swapchain, I'm basically referring to the window-created textures (like in D3D and Vulkan)

robust bough
#

ahh

#

maybe it could be renamed

long robin
#

I see what you're asking for now

robust bough
#

yeah

#

then the default can just be the default one provided

long robin
#

basically a shrimpler way to make the list of targets for rendering

robust bough
#

yep

#

then if there's a sentinel "default", it lets you have a single path for everything

long robin
#

I do have a couple functions for easing the creation of common kinds of textures

  Texture CreateTexture2D(Extent2D size, Format format, std::string_view name = "");
  Texture CreateTexture2DMip(Extent2D size, Format format, uint32_t mipLevels, std::string_view name = "");
robust bough
#

i might be doing textures wrong lol

#
  texture.UpdateImage({
    .offset = {0, 0, 0},
    .extent = {extent.x, extent.y, 0},
    .format = Fwog::UploadFormat::RGBA,
    .type = Fwog::UploadType::UBYTE,
    .pixels = pixels
  });```
#

i just proposed the "swapchain creation" idea because I think it would be nice to consolidate everything?

#

it would make it so then it's really shrimple to create targets and stuff

#

and then there's no need (for the user) to discriminiate between their own swapchains / window provided one

long robin
#

UpdateImage (and many other functions) has a bunch of defaults btw

robust bough
#

yeah I saw

#

the way Im going through this is just going through functions that look like what i need

#

and checking the source

long robin
robust bough
#

not sure? potentially a Fwog::Swapchain class

#

there you can keep track of the capabilities / what it can do

#

or a Fwog::RenderTarget

#

then you can pass that to render

long robin
#

hrm

robust bough
#

then the sentinal Fwog::RenderTarget::Default

#

or WindowProvided (naming is just bikeshed)

long robin
#

yeah a sentinel render target is something I've thought of

robust bough
#

that way the user is still being clear about who they're targetting

#

only difference is that they didn't create it

long robin
#

the only thing is that I dunno how much typing this would actually save. I guess you could have something like

auto rts = Fwog::CreateRenderTargetTextures({
  .extent = windowExtent,
  .colorFormats = {Fwog::Format::R8G8B8A8_SRGB, Fwog::Format::R16G16_SNORM},
  .depthFormat = Fwog::Format::D32_FLOAT,
});

the only problem is that it doesn't create the render targets (which include the loadOp and the clear value) as well

Fwog::Render({
  .name = "Bababooey pass",
  .colorAttachments = ???
  .depthAttachment = ???
  [&]
  {
    // draw calls
  });
#

so maybe CreateRenderTargetTextures also takes parameters to fill in the render target info structs

robust bough
#
auto bababooey_target = Fwog::CreateRenderTarget({
  .extent = windowExtent,
  .colorFormats = {Fwog::Format::R8G8B8A8_SRGB, Fwog::Format::R16G16_SNORM},
  .depthFormat = Fwog::Format::D32_FLOAT,
  .loadOp = Fwog::LoadOp::CLEAR,
  .clearColor = {0.0, 0.0, 0.0, 1.0f},
});

Fwog::Render(bababooey_target, [&] {
  // Draw calls
});
long robin
#
auto rts = Fwog::CreateRenderTargetTextures({
  .extent = windowExtent,
  .colorTargets = {{Fwog::Format::R8G8B8A8_SRGB, Fwog::LoadOp::DONT_CARE}, {Fwog::Format::R16G16_SNORM, Fwog::LoadOp::DONT_CARE}},
  .depthTarget = {Fwog::Format::D32_FLOAT, Fwog::LoadOp::Clear, 1.0f},
});
#

rts would be a structure containing a list of render targets (attachments) and a list of textures

#

then you can do

Fwog::Render({
  .name = "Bababooey pass",
  .colorAttachments = rts.colorAttachments,
  .depthAttachment = rts.depthAttachment,
  [&]
  {
    // draw calls
  });
robust bough
#

why still pass in the info in render?

#

seems wasteful

long robin
#

I'm not sure if I want to force usage of this new type

#

which owns its textures

robust bough
#

i dont see many downsides?

#

if they want to access the texture, you could make a method to access them somehow

long robin
#

the main one is that you can't easily take a random texture and make it a render target πŸ˜„

long robin
#

tbf I haven't had a need to do that

robust bough
#

this wouldn't let you do that?

#

because you can only create render targets, and render to them

#

you can't just yeet a random texture into a render target

long robin
# robust bough this wouldn't let you do that?

the idea in my head is that CreateRenderTargetTextures creates an object which owns some textures as well as some attachment info structs that reference said textures. The "problem" with this is if you want to reference an external texture (without owning it), or maybe reference a texture in multiple render passes

#

I just need to think about it some more

robust bough
#

Yeah the referenceing a single texture in multiple targets seems a bit iffy

#

are there any actual use cases for that?

long robin
#

yeah

robust bough
#

hm

long robin
#

maybe

#

yes

#

in 05_gpu_driven, the depth attachment is used in multiple render passes, but is only cleared in the first

robust bough
#
auto bababooey_target = Fwog::CreateRenderTarget({
  .extent = windowExtent,
  .colorFormats = {Fwog::Format::R8G8B8A8_SRGB, Fwog::Format::R16G16_SNORM},
  .depthFormat = Fwog::Format::D32_FLOAT,
  .loadOp = Fwog::LoadOp::CLEAR,
  .clearColor = {0.0, 0.0, 0.0, 1.0f},
});

auto using_depth_target = bababooey_target.CreateTargetUsing(Fwog::Target::DepthBuffer,
  .extent = windowExtent,
  .colorFormats = {Fwog::Format::R8G8B8A8_SRGB, Fwog::Format::R16G16_SNORM},
  .loadOp = Fwog::LoadOp::CLEAR,
  .clearColor = {0.0, 0.0, 0.0, 1.0f},
);
#

hm, someone has to own the textures

#

what about something like what you did with creating something that owns some metadata / textures

#

then you can create a render target from them? (and select which you use)

long robin
robust bough
#

so the render target doesn't own anything

#

it's just a way to create a render target from some textures

#
auto rts = Fwog::CreateRenderTargetTextures({
  .extent = windowExtent,
  .colorTargets = {{Fwog::Format::R8G8B8A8_SRGB, Fwog::LoadOp::DONT_CARE}, {Fwog::Format::R16G16_SNORM, Fwog::LoadOp::DONT_CARE}},
  .depthTarget = {Fwog::Format::D32_FLOAT, Fwog::LoadOp::Clear, 1.0f},
});

auto target = Fwog::CreateRenderTarget("Bababooey pass", rts);
Fwog::Render(target, [&]
{
    // draw calls
});
robust bough
#
  texture.UpdateImage({
    .offset = {0, 0},
    .extent = {extent.x, extent.y},
    .format = Fwog::UploadFormat::RGBA,
    .type = Fwog::UploadType::UBYTE,
    .pixels = fake_data.data()
  });

  bitmap->UnlockPixels();

  return &texture;```
```cpp
  Fwog::Cmd::BindGraphicsPipeline(pipelines.finalize_render.instance);

  auto sampler = Fwog::Sampler(Fwog::SamplerState{});

  Fwog::Cmd::BindSampledImage(0, *context.gui_texture, sampler);

  Fwog::Cmd::Draw(3, 1, 0, 0);```
```glsl
layout(location = 0) out vec4 o_color;
layout(location = 0) in vec2 v_uv;

layout(location = 0) uniform sampler2D gui_texture;

void main()
{
//    o_color = vec4(v_uv, 1.0, 1.0);
    o_color = vec4(texture(gui_texture, v_uv).xyz, 1.0);
}```
#

is there anything im doing obviously wrong here @long robin ?

#

im just getting a black screen

long robin
#

what's the issue

#

o

robust bough
#

and for some reason, when I launch this with renderdoc it crashes

#

texture(Fwog::CreateTexture2D({extent.x, extent.y}, Fwog::Format::R8G8B8A8_UINT))

long robin
#

not sure

long robin
#

if the app is on gh, I can try to build it

robust bough
long robin
#

does renderdoc crash, or just your app?

robust bough
#

the app

long robin
#

also is it a working directory issue

robust bough
#

but somehow it's stopped crashing

#

i commented out code that had to do with something else

fiery sorrel
#

What conditions does RenderDoc crash (like what code is commented in/out)

robust bough
#

its unrelated

#

it seems it's black?

#
  auto fake_data = std::vector<std::uint8_t>(extent.x * extent.y * 4);
  std::generate(fake_data.begin(), fake_data.end(), [](){
    return 250;
  });

  texture.UpdateImage({
    .offset = {0, 0},
    .extent = {extent.x, extent.y},
    .format = Fwog::UploadFormat::RGBA,
    .type = Fwog::UploadType::UBYTE,
    .pixels = fake_data.data()
  });```
long robin
#

hmm

#

can you share rdc capture or no

robust bough
#

There is all of this

#

(a bunch more too)

#

is that expected?

long robin
#

yeah that's a debugging feature πŸ˜„

robust bough
#

wish I could just, see what im calling with it

long robin
#

it should just have graphics API calls and resources

#

in theory

robust bough
long robin
#

see if making your sampler nearest fixes it

#

or making your texture unorm (since uint seems odd for a gui texture, assuming you want [0,1] color output)

#

srgb might also be a better choice

robust bough
long robin
#

combined depth+stencil formats were a mistake

long robin
#

I wish you could make a span from an initializer list {a, b, c, d} like you can with a vector

#

heap allocation just for minor programmer convenience 😩

heavy cipher
#

you can

#

not a std span, but your own

long robin
#

do I really wanna make my own span

#

also, C++ has no compound literals 😒

heavy cipher
#

lets roll a d15, what is your willpower stat

long robin
#

nat 1

dapper gorge
#

You accept a const T(&)[E]?

dapper gorge
#

incredible

long robin
#

the convenience of fwog hinges on this constructor existing

rugged notch
#

time to make your own innit

#

fun for the whole family

long robin
#

all this for a drop of convenience

#

I'll just put std::vector and accept the inevitable horrible perf when there are 2 heap allocs per frame

heavy cipher
#

ship fwog with a patch for the user's stl

long robin
#

step 1: get good at boxing

heavy cipher
long robin
#

well here is the prototype for this "simplified" render target system (try to ignore the epic auto formatting)

  // on init
  auto renderTargets = Fwog::MakeFoo({
    .extent = {800, 600},
    .colorTargets = {{Fwog::Format::R8G8B8A8_SRGB, Fwog::AttachmentLoadOp::DONT_CARE}, {Fwog::Format::R16G16_SNORM}},
    .depthTarget = Fwog::DepthStencilTargetInfo{Fwog::Format::D32_UNORM, Fwog::AttachmentLoadOp::CLEAR, {1.0f}},
  });

  // on render
  Fwog::Render(
    {
      .colorAttachments = renderTargets.colorAttachments,
      .depthAttachment = renderTargets.depthAttachment,
    },
    [&]
    {
      Fwog::Cmd::BindComputePipeline(...);
      Fwog::Cmd::BindSampledImage(...);
      Fwog::Cmd::Dispatch(...);
    });
#

it's a little shorter overall, but I'm still not super hot on the concept

#

I did find some places that could be otherwise be improved (changing pointers to optionals or references) at least

heavy cipher
#

what thar fuk is D32_UNORM

long robin
#

as opposed to D32_FLOAT

heavy cipher
#

is that actually a thing in ogl

tired sandal
#

yes

long robin
#

lol yeah I just checked vkFormat and it doesn't exist there

#

but it's real in opengl bleakekw

heavy cipher
#

what a horrible day to have eyes

tired sandal
#

whats the problem with it?

long robin
#

well there's probably a reason it doesn't exist in vulkan nervous

#

I'm guessing 8 bits of this are just discarded in practice

tired sandal
#

huh? why would it?

long robin
#

or it corresponds to VK_FORMAT_X8_D24_UNORM_PACK32

long robin
tired sandal
#

32 bit integers? nervous

#

D32_UNORM is an integer format

heavy cipher
#

D32 float is much better

long robin
#

depth textures are special creatures

#

btw D32_UNORM is not required in gl

heavy cipher
#

esp with reverse

long robin
#

damn that reminds me

#

welp, gotta blast

fiery sorrel
#

Me during moments of insecurity: "Man I gotta start using imperative mood or else I might not get hired"
Jakar:

#

ok looks like while its a good habit to have I feel a lot reassured that perfection really is the enemy of good

long robin
#

I'm slightly conchfused

#

is this a roast or something bleakekw

fiery sorrel
#

more of a self-roast

#

lately ive been like obsessed over stuff like "How to write good commit messages" and feeling insecure about it

#

like that everyone would make fun of me if I write 'Added' instead of 'Add' or not have the 50 word wrapping stuff all the time even in personal projects

#

so I was like 'I wonder how Fwog does the commit and merges' and I realize that perfect is the enemy of good

long robin
#

oh lol

fiery sorrel
#

and that there's a time and place to have different degrees of tryhard

#

basically im thanking you for reassuring me that id be fine

long robin
#

yeah a good commit message just gives you an overview of what changed

#

no need to format it perfectly or whatever

fiery sorrel
#

yea. My plan is keeping this loose, casual and informal in my local branch commits then in the remote when i squash merge I can practice the tryhard professional 'I dont want Linus to make fun of me' type of commits

long robin
#

does linus make fun of people for that

fiery sorrel
#

yea its where I started to becoming more awware of it

daring surge
#

this is funny to me

fiery sorrel
#

Let me dig out the post

long robin
#

also, there is a difference between making commits to the linux kernel (which is used by millions) and commits for your personal project that has maybe 1 or 2 users (including yourself)

daring surge
#

commit messages usually don't even matter usually

#

in a production environment you won't be commiting straight to whatever dev branch unless you're working on something very small

fiery sorrel
#

but yea there's a post where he gets pissed off at how ```
the fact that other projects apparently have so low expectations
of commit messages that these things get used is just sad. People
should try to compare the quality of the kernel git logs with some
other projects, and cry themselves to sleep.


(Torvalds, L 2012)


Torvalds, L. (2012, May). Add support for AR5BBU22 [0489:E03C] by REEJK Β· pull request #17 Β· Torvalds/Linux. GitHub. <https://github.com/torvalds/linux/pull/17#issuecomment-5659933>
daring surge
#

i am learning i do not like this man πŸ™‚

fiery sorrel
#

I noticed there's a strange weird 'thing' lately where I noticed where super respected authority figure who likes to yell at subordinates seem to attract a certain personality type that really likes to being yelled at

#

There's a lot of people who fantaize about having a Gordon Ramsay type to scold them in the kitchen. I see it in school too where like there was one whole team where all the subordinates considered the mocking feedback by the tech lead (whom does have strong technical skills) to be like being given angelic visions from the heavens

daring surge
#

normal

#

πŸ‘οΈ πŸ‘οΈ

fiery sorrel
#

You think he'd show up to Basedcon?

daring surge
#

the

fiery sorrel
#

i think he kinda has a point for linux repo because a lot of people work exclusively in TUI or CLI there

#

WAIT NO I JUST GOT IT

#

you do word-wrapping at
the

long robin
#

the

fiery sorrel
#

the

#

its me

#

the

#

but yea Jakar is my sanity check that like, no nobody is making fun of me that my personal projects have commit messages like 'fix bug maybe?'

long robin
daring surge
#

yeahhhhhh

long robin
#

bro probably never had to do webdev

fiery sorrel
#

Don't the Linus, Jonathan Blows and Casey Muratoris of the world hate web dev

daring surge
#

reminds me a lot of

#

i was just going to say jonathan blow

fiery sorrel
#

because it allows people of all kinds of skill levels to collaborate πŸ™ƒ

long robin
fiery sorrel
#

it makes sense for linux

long robin
#

so much overhead

#

yeah

#

but I ain't doin that shit for my shit

fiery sorrel
#

You know if I see that in a game dev project maybe it should be a red flag in an ironic way

daring surge
#

linux is relatively one of a kind

#

ye

fiery sorrel
#

Like 'oh shit is this run by a micromanager?'

long robin
daring surge
#

the game i'm working on has commits nothing like this, and they're all even squashed from PRs

fiery sorrel
#

man the CMake Generating Stuff loading can be a productivity drain as I get distracted forgetting about it lol but this is an enlightening convo

daring surge
#

no one gives a fuck because we're not managing an open source project with thousands of contributors (potentially infinite), and we're not able to slow ourselves down

#

our productivity needs to be higher, and our barrier for entry doesn't need to be as low

fiery sorrel
#

I think I'd pick up a lot of the 'how to write code professionally' skill better once I am writing code professionally more at my internship

#

I do try and like self learn but its hard to tell the balance on my own

daring surge
#

i think like a week after starting i accidentally added every single engineer (~75 people) to my PR on accident because of some weird git shit, and one single person messaged me telling me how to fix it and that was it KEKW

fiery sorrel
#

LMFAO thats amazing

long robin
#

mmm pushed some breaking changes

heavy cipher
# long robin mmm pushed some breaking changes

when i make breaking changes:
for the good of the code
actually improving
aesthetic
when i have to contend with someone else's breaking changes:
you fucking donkey
no respect for my time
big nothingburger for a syntax change

long robin
tired sandal
#

still better than to deal with raw opengl froge

fiery sorrel
#

im gonna be dealing with raw d3d12 (or maybe d3d11? idk) in my win32api experiments (I never touched the d before)

#

I figured since I am using Fwog and not touching Vulkan I should have some raw api to be regularly exposed to anyways to not get too soft

rugged notch
#

это закаляСт Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€

fiery sorrel
#

what am i reading

#

ah yes

#

is d3d11 still worth using? Because if it is I can try it as I want to contribute to #d3d11-tutorial-wip too if I use that

#

but otherwise I'd prefer to use the more modern d3d12 if its not as good ROI

heavy cipher
#

is this the right channel

fiery sorrel
#

oh sorry

#

Its because I saw the word 'raw opengl'

#

and then it flow naturally

#

I apologize friend

tired sandal
#

does fwog work with imgui? since imgui changes the state of the context

long robin
#

the default gl imgui backend undoes all changes it makes to the state

long robin
#

I use it in the fwog examples with no issues

rugged notch
#

Does nobody look at the examples

#

It's getting kind of comical at this point

long robin
#

idk but at least they were fun to make

fiery sorrel
#

(hence why I end up making a separate template meant for Fwog: https://github.com/ClementineAccount/Fwog-CMake-Glfw-OpenGL-Template which has Dear Imgui, shows Fwog working out of the box with FetchContent, the depth buffer enabled by default, using single draw instead of multidraw (more noob friendly) in a project u can use as a base to do whatever, and skybox example as that was one thing the examples didnt show how to do)

#

I kinda wish Jaker would give feedback on stuff he wants changed for it or if he wants to take it/link it on the Fwog page

fiery sorrel
#

but he went forward instead of side

long robin
fiery sorrel
#

🫒

long robin
#

I think it's a good exshrimple of a standalone project

#

no changes are really needed since you don't do anything heinous in the cmake

fiery sorrel
#

Thanks!

#

I do think like this stuff could be in its own .h files and stuff but I also wanted to make it look as close to Deccer's Cmake as I can for first version at least.

#

Arguably they can even be moved to the .Lib but I actually rather keep a Simple Template here and I'd just make the more refactored version either as an additional template (that this can link to) or put it into Alberquerque

long robin
#

I think it's good

fiery sorrel
#

Thanks :)

tired sandal
long robin
#

fr

#

this is where ImGui is set up

tired sandal
long robin
#

which is implemented in the examples

fiery sorrel
#

deferred and gltf viewer has them

long robin
rugged notch
#

Itd help if you opened the files I think

fiery sorrel
#

Interview with the Help Vampire

rugged notch
#

Nahh, didnt mean to imply that

long robin
#

tbf I think raildex was expecting a single example that used imgui

fiery sorrel
#

nah its ok I just had that line in my mind for awhile

rugged notch
#

Just like, open the repo in a vscode thing in the browser, ctrl+shift+f imgui

fiery sorrel
#

I was a newborn vampire, weeping at the beauty of the 'guys how do i use gcc'.

long robin
#

that's a lot of thingies to look at

golden schooner
#

its quite sad actually

#

given how long raildex is on this very server already

#

you shouldve knowve raildex!

tired sandal
golden schooner
#

now make something great with fwog πŸ™‚

long robin
#

uh, they just redirect when you click on them

#

I managed to get to this cursed page by searching for glTextureView in the search bar

long robin
#

@fiery sorrel I linked your thingy in the readme

#

I might put it in an extended "examples" or "showcase" section of the readme in the future to give it better visibility

fiery sorrel
#

Its in a good spot

#

One reason I made that is that its pretty easy to assume 01_hello_triangle is a 'starting template' otherwise too, at least I made that "mistake" (arguably its actually ok if someone knows to then go back and fetch/gitsubmod Fwog as a library but this makes it more obvious to ppl who aren't as familiar)

long robin
#

@tired sandal how do you feel about this shrimple thing for a debug callback

  struct ContextInitializeInfo
  {
    void (*debugMessageCallback)(const char*) = nullptr;
  };

  void Initialize(const ContextInitializeInfo& contextInfo = {});
tired sandal
#

love it

long robin
#

I don't see a use for warning levels atm because other severities would be handled by exceptions or asserts

long robin
golden schooner
#

debugMessageCallback is oddly specific to the underlying tech, but i frogive you, because fwog only deals with one specific one, other wise its a huge red flag in abstracting things

long robin
#

I'm not understanding

#

ah

#

I should clarify that this has nothing to do with the opengl debug callback frog_sweat

golden schooner
#

good come back πŸ˜„

long robin
#

it's solely for logging stuff that fwog is doing

golden schooner
#

i thought so

#

but your right side of the brain was hanging on to glDebugMessageCallback

long robin
#

idk a better way to name this

heavy cipher
#

whenever this callback is issued the user's computer calls Jaker on a phone using a text-to-speech program

golden schooner
#

logMessageCallback perhaps, from on top of my head

#

debug is misleading

long robin
#

hmm

#

I'm gonna use it for logging when GL objects are created and destroyed, and maybe a few other things

long robin
#

OpenGL lets you set a message callback as well, which is unrelated to this one

#

and people typically call it the "debug message callback", which can be easily conflated due to my naming

tired sandal
#

oh wait, it was that "oddly specific to the underlying tech" that put me off KEKW
I thought he meant opengl has some platform specific stuff for that

long robin
#

the gl one is for logging API misuse (validation) mainly

long robin
#

maybe I'll call the new thing perfMessageCallback or performanceMessageCallback

tired sandal
#

as long as I can retrace what Fwog does I am happy frogeheart

heavy cipher
#

doc string: "Use this callback to lower perf"

#

btw what will this cb do? i am curious now

long robin
golden schooner
#

niet to "performance" or "perf"

long robin
#

raildex requested it because of some C++ lifetime issues (classic), but I see it as a way for the user to see when Fwog is implicitly creating and destroying shit (gl objects), thus affecting πŸ…±οΈerf

tired sandal
#

I wouldn't expect Fwog::Shader to just store a pointer to the source and instead store it internally frogdelet

long robin
#

it doesn't store anything itself besides a gl handle

#

nor does it reference anything

#

the issue in your case was referencing the shaders in a returned object (pipeline create info)

tired sandal
#

oh wait it was the pipelinecreateinfo

#

yeah. i would it expect it to be owning (because well RAII) frogdelet

heavy cipher
#

the workers must own the means of pipeline production comrade Jaker

long robin
#

because shaders can be used in multiple pipelines

#

I guess this is one of the downsides to using parameter structs- the user might pass around the struct before actually calling the function

#

Rule of thumb when using these: call the function immediately. Ideally, you don't even reference the parameter struct by name

#

auto foo = CreateFoo({.bar = 2});

long robin
#

Shader is not copyable I'm afraid

#

it owns an OpenGL shader object

long robin
snow sun
#

my brain cant fit c++ rules

final cove
#

c++ page fault

long robin
#

I cannot comprehend what I'm doing wrong here

#

uh

#

I think I see

#

the first arg had to be std::format_string<Args...> fmt for the compiler to see

dapper gorge
#

I would look at this

#

unfortunately I am currently in the sleeping device

#

(bed)

long robin
#

it's aight, I fixed it already (second godbolt link)

dapper gorge
#

epic

golden schooner
long robin
#

now there is ebic logging

Fwog: Created buffer with handle 1
Fwog: Created buffer with handle 2
Fwog: Destroyed buffer with handle 2
Fwog: Destroyed buffer with handle 1
long robin
#

well this compiles
nullptr_t bababooey = *(nullptr_t*)(1234);

#

actually I don't even know why I'm surprised. It's not like I directly assigned it a weird value

#

I accidentally pushed this
/// @brief Callback

long robin
daring surge
#

DESPAIR just use streams

long robin
#

byeah

fiery sorrel
#

wheres fwog for 2023 dr deccer

long robin
#

I'm trying to use va_list right now and it's like dragging my froge through a field of broken glass

daring surge
#

nah i joke

#

i love fmt

long robin
#

yeah but it's not supported except on the version of gcc that released like a month ago bleakekw

#

I guess I'll have to unironically use streams

#

except I forgor how to make a stream from a fixed size buffer

#

hmm, how do I get the number of args from a printf format string? va_start requires a count except in C23

#

apparently there is no standard way, epic

daring surge
#

i've never even tried to use <format>

#

but i also don't have to mind adding a lib

long robin
#

I'm trying to format in exactly one place

#

I don't want to include a lib for one line of code bleakekw

long robin
#

apparently it is impossible to do this in c

void printer(const char* fmt, ...)
{
  char buf[512];
  vsnprintf(buf, 512, fmt, /* how tf do I send the variadic args here */);
}
#

va_start requires a count, which is encoded in the format string, but I have to parse it manually to get that bleakekw

#

ass language

#

it only starts to not suck once you have <format>

long robin
#

hinged af code

      char messageBuffer[1024] = {};
      std::stringstream stream;
      stream.rdbuf()->pubsetbuf(messageBuffer, std::size(messageBuffer) - 1);
      ((stream << args), ...);
      context->verboseMessageCallback(messageBuffer);
fiery sorrel
#

hinged

#

Thinking of making my mid July blog post a review of Fwog as a user @long robin

#

Should I refer to you as 'a friend's' or something πŸ€”

long robin
#

shure

#

"homie" works too

fiery sorrel
#

Might have a section on the existing examples too.

#

ah i can link it together

#

anything in particular u want me to focus on in addition that stuff? @long robin

long robin
#

it's your blog

fiery sorrel
#

ok!

long robin
#

but ye those topics are good

fiery sorrel
#

didnt there used to be a frog thumb up?

#

oh there he is

daring surge
#

be more negative!!!

daring surge
#

i kid, if this was not conveyed through text

#

i'm like four steps removed from even possibly having anything negative to say about fwog

long robin
#

same

daring surge
#

1 exclamation mark is a sarcasm indicator to me dogekek

fiery sorrel
#

oohh u meant the review

daring surge
#

yuhhh

fiery sorrel
#

I thought u wanted Jakar to be more negative towards me

#

LMFAO

long robin
#

somehow the stream contains the text, but the buffer isn't written to thonk

#

@fiery sorrel can you run this code in a local project (using msvc) as a sanity check

#include <iostream>
#include <sstream>

template<class... Args>
void printy(char* buffer, int bufferSize, Args&&... args)
{
    std::stringstream stream;
    stream.rdbuf()->pubsetbuf(buffer, bufferSize - 1);
    ((stream << args), ...);
    printf("%s\n", buffer);
}

int main()
{
    char buf[16] = {};
    printy(buf, std::size(buf), "baba", "booey");
}
#

you can just use a project that you have open too

fiery sorrel
heavy cipher
fiery sorrel
#

Wasnt it Jakar at some point of the canon

#

lets go

long robin
#

I was suggesting plugging the code into an existing project so you wouldn't have to create a new one (since it was just for a shrimple test)

#

I guess it's easy to make a new VS project though

tired sandal
#
[...]/external/fwog-src/src/detail/VertexArrayCache.cpp:66:15: error: no member named 'InvokeDebugMessageCallback' in namespace 'Fwog::detail'; did you mean 'InvokeVerboseMessageCallback'?
[build]       detail::InvokeDebugMessageCallback("Destroyed vertex array with handle {}", vao);
[build]       ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
[build]               InvokeVerboseMessageCallback
[build] [...]/external/fwog-src/include\Fwog/detail/ContextState.h:87:8: note: 'InvokeVerboseMessageCallback' declared here
[build]   void InvokeVerboseMessageCallback(std::format_string<Args...> fmt, Args&&... args)
[build]        ^
[build] 2 errors generated.
#

i am on the newest main

long robin
#

yeah I goofed

#

resharper failed to refactor the function correctly and somehow shit still built

long robin
#

just see if it prints anything

fiery sorrel
long robin
#

ok your buffer is empty too

#

idk what's wrong then

#

I noticed that rdbuf returned a null pointer, which is rather sus

heavy cipher
long robin
#

help me out here brother

#

I have no clue which doc that is from

#

ah, it's setbuf

heavy cipher
#

what are you trying to achief, chief?

long robin
#

I want to achief printing to a buffer of my own provision

#

attempt 1 was using format_to_n, which didn't work because gcc sucks

#

attempt 2 was using va_start and vsnprintf, which didn't work because c sucks

#

attempt 3 (this one) is me trying to back a stream with my own buffer, then write to it

#

but the answer provided by SO uses IB, amazing bleakekw

heavy cipher
#

if your own buffer is a std::string, then you can call str()

long robin
#

the stringstream, you mean?

heavy cipher
long robin
#

std::string has no member called str

heavy cipher
#

yes, call str() on the stringstream

#

man i fucking love *stream names in the stl, so descriptive

long robin
#

yeah that'll work, but muh unnecessary allocations

heavy cipher
#

wher

long robin
#

I presume the stringstream can alloc when writing to it, as might calling str

#

but it's a smol worry

heavy cipher
#

i do not follow

long robin
#

where does the storage for stringstream come from

heavy cipher
#

you are providing it

#

when calling str()

long robin
#

holy shit str is overloaded bleakekw

heavy cipher
#

fml

long robin
#

it does two completely different things

heavy cipher
#

yes i mean call str(std::string&/&&)

long robin
#

yuh

#

I think the other overload will work for me now, actually

heavy cipher
#

you can also keep the stream around and rewind it

heavy cipher
#

jeez will you are getting paid bank for this commercial, get off your phone

long robin
#

willy isn't free of his phone addiction

heavy cipher
long robin
#

justn't like myself

heavy cipher
#

age is just a number int old = true;

long robin
#

@tired sandal latest commit is no longer failing to build btw, and it has the logging callback thingy (you provide it in Fwog::Initialize now)

golden schooner
#

setting up a project with vs only from scratch for c++ is a can of worms and you can make 2139048094358 things wrong

tired sandal
golden schooner
#

ah great, thank you discord

tired sandal
#

cmake my love

long robin
#

@golden schooner

rugged notch
long robin
#

wtf two health bars

rugged notch
#

My beloved

golden schooner
#

Second Crack xD

dapper gorge
long robin
#

I like how they don't even start exporting materials until "100%"

dapper gorge
#

he enabled material baking KEKW

#

it's over

long robin
#

uh

rugged notch
#

🫡 froge_sad

#

You have sealed your fate

long robin
#

I done goofed

golden schooner
#

does an example level come with deez mups?

golden schooner
#

the level in the screenshots, does it come witht he asset pack?

heavy cipher
golden schooner
long robin
#

enjoy imgur link

dapper gorge
#

I dunno why unreal didn't just use the glTFforUE4 plugin instead of making their own, shittier version

long robin
#

it doesn't like when you don't bake the materials, yo

golden schooner
#

: S

dapper gorge
long robin
#

that do be working

#

lmao try to spot the model

#

I call this one "pale gray dot"

dapper gorge
#

I counted the pixels, it's 4

long robin
#

here is a zoomed-in version

#

that's as close as I can get in windows 3D viewer

dapper gorge
#

rasterizationℒ️

heavy cipher
#

turd.gltf

golden schooner
#

stupid 1m vs 100cm thing

long robin
#

some of the meshes seem to be backwards

golden schooner
#

hmm

long robin
#

disabling face culling significantly unfucks it

#

feels hacky though

golden schooner
#

side panels do be looking a little dubious

#

but the space the sun shines on looks neat, almost as if you have some bloom going already

long robin
#

they are actually supposed to look like that

#

I'm not using normal maps btw

golden schooner
#

oh

long robin
#

so it's just straight albedo and πŸ…±οΈertex normals

golden schooner
#

why are you not using normals?

long robin
#

that's coming in the pbr update

golden schooner
#

of what

heavy cipher
#

pbr dlc froge_love

golden schooner
#

the asset pack?

long robin
#

03_gltf_viewer

golden schooner
#

oh

#

right

long robin
#

the asset pack comes with peebeeare materials ofc

golden schooner
#

how big is the model btw with its assets, exported to gltf/glb?

long robin
#

131mb with 1024^2 materialz

golden schooner
#

hmm ~twice as old sponza

#

if i show you a receipt of me buying that pack too, would you be willing to share the gltf?

long robin
#

ok

#

btw gltfpacked version (just tc) is 22mb

fiery sorrel
#

I noticed that Fwog heavily relies on either std::optional or std::unique_ptr a lot of its constructors call OpenGL functions like glNamedBufferSubData which means that that code must be called after the window is initialized (and hence Fwog is initialized). At least, in the case of Deccer's Cmake Template I can't just have class member variables living in an Application.hpp without there being issues (because Application.hpp's constructor is called before Run()).

long robin
#

lol materials look like ass, I think I need to re-export

long robin
fiery sorrel
#

no I didnt mean that Fwog uses it. I mean I have to use either optionao r unique ptr to use Fwog stuff

long robin
#

why do you have to use unique_ptr?

golden schooner
fiery sorrel
#

no its an option.

heavy cipher
golden schooner
#

i dont think i can install ue here on lunix, and i dont want to switch to windows :3

fiery sorrel
# golden schooner that is why i load all the shtuff in Load() not in Initialize()

It I make a camera class like

    class Camera
    {
    public:
        Camera();
        void Update();
    
    private:

        struct CameraUniforms {
            glm::mat4 viewProj;
            glm::vec3 eyePos;
        };
        
        Fwog::TypedBuffer<CameraUniforms> cameraUniformsBuffer;

        //Skybox doesn't pass in the translation
        Fwog::TypedBuffer<CameraUniforms> cameraUniformsSkyboxBuffer;

        glm::vec3 camPos = glm::vec3(3.0f, 3.0f, 3.0f);
        glm::vec3 target = glm::vec3(0.0f, 0.0f, 0.0f);
        glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);

        float nearPlane = 0.01f;
        float farPlane = 5000.0f;

        CameraUniforms cameraStruct;
    };
#

That Fwog means that I cannot just have a Camera myCamera inside ProjectApplication.hpp

#

I can only have an std::optional<Camera> myCamera

golden schooner
#

i dont have any glismin my camera, because you perhaps stuff more things into the cbuffer where youd store camera stuff as well

long robin
#

btw glb turns into 529mb when I export 2048^2 textures

golden schooner
#

not too bad

#

gltfpack will perhaps half it?

long robin
#

just 70mb after gltfpackerino is done

fiery sorrel
#

So if I am calling any Fwog constructor, it has to be called inside Load() which means I have to make that variable's constructor not called when ProjectApplication's constructor is called.

long robin
#

i c

fiery sorrel
#

This is actually fine tbh

#

I don't mind stuffing std::optional everywhere until I eventually will figure out a better way to organize and architecture my code over time

long robin
#

yeah you can use std::optional to defer initialization as you noticed

fiery sorrel
long robin
#

you can make your own deferred init class too

#

that way you don't have the "overhead" of a single bool

fiery sorrel
#

constructor() = delete;?

long robin
#

no

fiery sorrel
#

How do I make a deferred init class

#

acutally imma google that word dw

long robin
#

a class that holds some aligned storage, then provides a construct method

heavy cipher
#

i'd say most likely the architecture is the problem, and I wouldn't do deferred init

#

make your renderer do this stuff, not the camera

long robin
#

you can embrace long initializer lists

dapper gorge
#

Reject constructors, embrace static Self make(CreateInfo)

fiery sorrel
#

The renderer itself would need to be an std::optional if its a class tho with that same limitation but it is better to have one optional than a bajillion (or ensured its constructed after Iniitalize() so not stored inside Application.hpp*)

*context: Deccer's Cmake Template

#

but dw im not askin for help or anything just an observation