#Foundations - Learning Graphics Programming with the Zig Programming language

1 messages ¡ Page 5 of 1

delicate delta
#

I got it from deccer

elder kettle
#

Nah I just like that one

#

I made my own but I'm tempted by that one as well

delicate delta
#

it's better than default

elder kettle
#

I can't decide what I like more

#

I made mine go further towards the textured/tactile aesthetic

#

But the steam-like one is probably the best one can do with a flat aesthetic

#

Goddamn I miss 2008 era steam

delicate delta
#

that one just keeps looking better the more I look at it

#

hrm

elder kettle
#

I can share the cfg tomorrow if you want to try it

delicate delta
#

I think the colors in that one don't like don't mesh, like the green and the blue window title bar, and at first that's what I noticed but I think it doesn't matter, because I like the other details

#

there's like depth too

elder kettle
#

The greens are from the user code not part of the theme

delicate delta
#

oh

elder kettle
#

The grey ones are the default color

#

The greens are either just set manually on the left panel or user-selectable on the right panel in that "debug color" picker

delicate delta
#

I like it

#

I think yours is better

elder kettle
#

I'll paste it here tomorrow if I remember I'm in bed now so don't have access to it

delicate delta
#

thanks

#

I'm trying to get multiple lights working now

#

just two

#

then I'll add a drop down to pick the object type and then I'm done with this scene

#

I'm going to add another scene with lighting + textures, and then update my solar system

elder kettle
#

Solar system? froge_love

delicate delta
#

yeah it's pretty basic though :P

#

not at all realistic lol

elder kettle
#

Just for the sake of making one or is it for a sun ephemeris system or something

delicate delta
#

it's in the book

#

it's just the sun, the earth, and a moon

#

and a space shuttle now

elder kettle
#

Ah ok so a little space scene

delicate delta
#

yeah

#

there's a later chapter that does a sky box, then I can do a starry sky

elder kettle
#

I made a similar model designed just for the celestial mechanics of stuff in the sky for Jake a while back

#

For the sun and moon anyways

delicate delta
#

yes I remember that

elder kettle
#

That one had a simplified output though it wasn't something you'd use for a full solar system model

#

It just put the sun in the right place in the sky

delicate delta
#

it was pretty cool, this one is just a toy

delicate delta
elder kettle
delicate delta
#

Thanks I will try it rightnow!

#

I changed the grab handles a little

elder kettle
#

What resolution are you running

delicate delta
#

4k

elder kettle
#

Ok that's probably why

#

it looks quite different than mine

delicate delta
#

width=3840;
height=2400;

elder kettle
#

The offsets and stuff must be interpreted as pixels

delicate delta
#

yeah at this resolution I had to really learn to use relative global font scale for everything

#

because anyone would load my game and would be able to see like the top left corner

#

and that's it

elder kettle
#

You might need to bump up the border sizes

ivory verge
#

i wonder how Iosevka SS02 would look like in imgui

delicate delta
#

hrm

#

maybe I just need to make it font scale aware

#

I don't want to hard code to make it look good at 4k

queen hinge
#

ah yes
spleens

delicate delta
#

what are otf

elder kettle
#

Ah I see now there's no shadow width option just a hard-coded 1px shadow and shadow color

queen hinge
#

open type font

#

more flexible extension of ttf

ivory verge
#

i posted a spleen using screenshot somewhere

#

ah

#

#graphics-resources message

delicate delta
elder kettle
#

Is that with a bigger border size

#

that looks better but the shadow is still tiny

delicate delta
#

hrm no I applied scale to what was there

elder kettle
#

Ah

ivory verge
#

scale blurs ze fonts somehow

delicate delta
#
    style.FrameBorderSize = 1.0 * scale;
    style.ScrollbarRounding = 0.0;
    style.TabBarBorderSize = 2.0 * scale;

    style.WindowPadding = c.ImVec2{ .x = style.WindowPadding.x * scale, .y = style.WindowPadding.y * scale };
    style.FramePadding = c.ImVec2{ .x = style.FramePadding.x * scale, .y = style.FramePadding.y * scale };
    style.ItemSpacing = c.ImVec2{ .x = style.ItemSpacing.x * scale, .y = style.ItemSpacing.y * scale };
    style.ItemInnerSpacing = c.ImVec2{ .x = style.ItemInnerSpacing.x * scale, .y = style.ItemInnerSpacing.y * scale };
    style.TouchExtraPadding = c.ImVec2{ .x = style.TouchExtraPadding.x * scale, .y = style.TouchExtraPadding.y * scale };
ivory verge
#

but you can modify that when you addfontfromfilething where you tell it what fontsize you want

delicate delta
#

scale is io.FontGlobalScale

#

ok, I changed it considerably from yours but I like it

#

thanks!

#

this is way better

#

I fixed some other stuff

#

I had to translate that C++ to zig, and this is what I have now (in zig):

pub fn theme(scale: f32) void {
    var style = c.igGetStyle().*;

    // Increase border thickness
    style.FrameBorderSize = 1.25 * scale;
    style.WindowBorderSize = 1.25 * scale;
    style.PopupBorderSize = 1.25 * scale;
    style.TabBorderSize = 1.25 * scale;

    // Adjust rounding 
    style.FrameRounding = 2.0 * scale;
    style.WindowRounding = 2.0 * scale;
    style.ScrollbarRounding = 2.0 * scale;
    style.GrabRounding = 2.0 * scale;
    style.TabRounding = 2.0 * scale;

    // Increase left padding
    style.WindowPadding = c.ImVec2{ .x = 20 * scale, .y = 6 * scale };
    style.FramePadding = c.ImVec2{ .x = 10 * scale, .y = 4 * scale };

    // Enhance shadow and borders for depth
    style.Colors[c.ImGuiCol_BorderShadow] = c.ImVec4_ImVec4_Float(0.00, 0.00, 0.00, 0.60).*;
    style.Colors[c.ImGuiCol_Border] = c.ImVec4_ImVec4_Float(0.40, 0.40, 0.40, 1.00).*;

    // Adjust background colors for better contrast
    style.Colors[c.ImGuiCol_WindowBg] = c.ImVec4_ImVec4_Float(0.15, 0.15, 0.15, 1.00).*;
    style.Colors[c.ImGuiCol_PopupBg] = c.ImVec4_ImVec4_Float(0.13, 0.13, 0.13, 1.00).*;
    style.Colors[c.ImGuiCol_FrameBg] = c.ImVec4_ImVec4_Float(0.20, 0.20, 0.20, 1.00).*;
    style.Colors[c.ImGuiCol_FrameBgHovered] = c.ImVec4_ImVec4_Float(0.28, 0.28, 0.28, 1.00).*;
    style.Colors[c.ImGuiCol_FrameBgActive] = c.ImVec4_ImVec4_Float(0.35, 0.35, 0.35, 1.00).*;

    // Enhance button colors
    style.Colors[c.ImGuiCol_Button] = c.ImVec4_ImVec4_Float(0.25, 0.25, 0.25, 1.00).*;
    style.Colors[c.ImGuiCol_ButtonHovered] = c.ImVec4_ImVec4_Float(0.33, 0.33, 0.33, 1.00).*;
    style.Colors[c.ImGuiCol_ButtonActive] = c.ImVec4_ImVec4_Float(0.40, 0.40, 0.40, 1.00).*;

    // Adjust header colors
    style.Colors[c.ImGuiCol_Header] = c.ImVec4_ImVec4_Float(0.22, 0.22, 0.22, 1.00).*;
    style.Colors[c.ImGuiCol_HeaderHovered] = c.ImVec4_ImVec4_Float(0.30, 0.30, 0.30, 1.00).*;
    style.Colors[c.ImGuiCol_HeaderActive] = c.ImVec4_ImVec4_Float(0.37, 0.37, 0.37, 1.00).*;

    // Enhance slider and scrollbar for better visibility
    style.Colors[c.ImGuiCol_SliderGrab] = c.ImVec4_ImVec4_Float(0.45, 0.45, 0.45, 1.00).*;
    style.Colors[c.ImGuiCol_SliderGrabActive] = c.ImVec4_ImVec4_Float(0.55, 0.55, 0.55, 1.00).*;
    style.Colors[c.ImGuiCol_ScrollbarGrab] = c.ImVec4_ImVec4_Float(0.40, 0.40, 0.40, 1.00).*;
    style.Colors[c.ImGuiCol_ScrollbarGrabHovered] = c.ImVec4_ImVec4_Float(0.50, 0.50, 0.50, 1.00).*;
    style.Colors[c.ImGuiCol_ScrollbarGrabActive] = c.ImVec4_ImVec4_Float(0.60, 0.60, 0.60, 1.00).*;

    // Ensure text is clearly visible
    style.Colors[c.ImGuiCol_Text] = c.ImVec4_ImVec4_Float(0.90, 0.90, 0.90, 1.00).*;
    style.Colors[c.ImGuiCol_TextDisabled] = c.ImVec4_ImVec4_Float(0.60, 0.60, 0.60, 1.00).*;

    // Adjust spacing for better separation of elements
    style.ItemSpacing = c.ImVec2{ .x = 8 * scale, .y = 4 * scale };
    style.ItemInnerSpacing = c.ImVec2{ .x = 4 * scale, .y = 4 * scale };
    style.TouchExtraPadding = c.ImVec2{ .x = 2 * scale, .y = 2 * scale };

    // Adjust sizes
    style.ScrollbarSize = 14 * scale;
    style.GrabMinSize = 10 * scale;

    c.igGetStyle().* = style;
}

const c = @import("../c.zig").c;
#

a buch of zigisms visible there 😅

#

I am really happy with how this looks now though

#

could use some right padding on some places

#

spleens hrm

#

I do not like proggy clean

delicate delta
#

ok I'm going to work on switching the models portion of that lighting scene and then move on to textured lighting and fixing my solar system

#

then done with this chapter

delicate delta
#

Also yesterday I tried NSight Graphics and wow it's fantastic

delicate delta
#

ok next is just a directional light with a dolphin with its texture, and then the solar system work

#

this seems weird though

ivory verge
#

it do be

#

but its a beautiful orange

delicate delta
#

it's the white light that's causing that

#

I'm not too worried about lighting bugs, this C++ with OpenGL book is light on math, and I still have to read all the actual math book chapters on lighting

ivory verge
#

shame that logl also fucks that up quite a bit

#

mixing surface and light properties

queen hinge
#

imma guess specular is incorrectly applying to backfaces for some reason?

ivory verge
#

🐛

delicate delta
#

not sure, I followed the book's C++ pretty literally

#

when I get to the actual lighting math I'll probably have a better grasp and understanding to try and debug it

#

I understand the math at a high level though

ivory verge
#

possible that the maths in ze book had an error

#

a flipped sign or something

delicate delta
#

I also just add these lights together because I have no idea how to have multiple lights, and for the most part seems to work pretty well

#

it's just a loop that adds each light's output to the color vec4 I emit from the frag

#

I just made that up

#

the books cover multiple lights later

#

so maybe that's the issue there idk

#

it could also be my weird coordinate system again

#

almost a year now of graphics programming with zig

queen hinge
delicate delta
#

it's fun

#

I stopped doing pretty much anything else since, haven't watched a single tv show, movie, read a book, or played a video game since

#

I still exercise regularly

queen hinge
#

you will (probably) fall off this train eventually -- would advise sometimes taking breaks

ivory verge
#

you have read programming books though

delicate delta
#

true

#

I have an equally high stack of books I was planning on reading sitting abandoned now though

ivory verge
#

my living room table has stacks of books which i want(ed) to read :3

queen hinge
#

ya'll wanted to read books?

ivory verge
#

yeah

#

science fiction shtuff

queen hinge
#

my whole life
I've never really wanted to read books
still don't KEKW

delicate delta
#

my todo list of books so is crazy I have warhammer 4k books, history books, fiction, I have the barbara streisand autobiography in there, I read everything

ivory verge
#

im only into science fiction and i used to read universe/quantum mechanics related stuff

#

tiny bit of fantasy

delicate delta
#

I love biographies

elder kettle
#

Read Greg Egan

ivory verge
#

i have robert silverberg to finish first

#

and the other dude's stuff, hard science fiction

elder kettle
delicate delta
#

vernor vinge and KSR are my favorite scifi authors

elder kettle
#

His books have like online diagrams and notes to explain the physics concepts lol

ivory verge
#

i wanted to go study quantum mechanics back when i was a kid

delicate delta
#

I read about the delayed-choice quantum eraser once and thought it was cool, but I know I don't understand any of it

elder kettle
#

I don't really understand it either since I've only seen like a pop science description of it I've never actually worked through a delayed choice problem

#

It's more of a curiosity that falls out of the math in a contrived situation than something that actually crops up regularly

#

Most of what we studied were practical things relevant to experiments

delicate delta
#

the wikipedia article section about the consensus being no retrocausality takes all the fun out of it, so maybe it's better to not understand it :P

elder kettle
#

Well it's the same spooky behavior as any other distributed entanglement problem

delicate delta
#

I don't understand any of it

elder kettle
#

It seems counterintuitive because of the assumption that the probabilities refer to just the contents of the experiment and not the whole universe

#

entanglement is basically identical to mixing up two cards and then mailing each one to someone on opposite sides of the world

#

surprise: if one person opens the envelope and knows they got the red card, they immediately know the other person got the blue card

delicate delta
#

spooky

#

that's a really great explanation

elder kettle
#

the strange part is that the superposition state isn't (card state) = Red + Blue, it's (world state) = (You got red and I got blue) + (You got blue and I got red)

#

The former implies that there is some sort of faster-than-light communication that makes sure that only one of each color card exists (impossible)

#

the latter implies that local realism doesn't exist (scary but undeniable)

delicate delta
#

what does local realism mean?

elder kettle
#

hang on I'm looking for something

#

Ok I can't find it

#

unfortunately this is hard to explain in any non mathematical way but it basically means the universe is weird lol

#

It has to do with the EPR paradox but it basically means there cannot be a straightforward explanation such as that the outcome of who gets which card is "secretly" predetermined by some hidden variable so the measurement is actually not random

#

You can do experiments to prove that the cards are truly randomly distributed yet clearly correlated since we will never both get a blue card or a red card

delicate delta
#

Interesting

elder kettle
#

It basically means that the counterintuitive quantum behaviors are fundamental and not just an apparent thing that can be explained classically by some unknown factor

delicate delta
#

I find just the basic forces of nature, like weak and strong force, just as mysterious as that. Honestly I mostly try to avoid thinking about it. I don’t understand and it doesn’t help me personally and I probably just mostly misunderstand and can’t draw any conclusions from it

elder kettle
#

Tbf neither can 99.999% of humanity lol it takes some very impractical study to understand them even at a surface level like I do

delicate delta
# queen hinge you will (probably) fall off this train eventually -- would advise sometimes tak...

I want to address this. I don’t burn out. I have a daily routine aligned with my goals. Every day I have a choice as to how I will spend that day’s time. The time will pass and if I am alive at the end of it I will have spent it doing something. My choice is based on a daily routine that I steer based on my goals. When my goals change I change my routine. I cannot do otherwise. It’s just how I am.

queen hinge
#

lucky

delicate delta
#

I am a machine

queen hinge
#

<- is incapable of goal setting because if I set a proper goal for myself I end up doing something completely unrelated even though without setting that goal I would've actually done something related

elder kettle
#

That's not a problem

#

Set several goals and then procrastinate on one by doing another

delicate delta
#

We are all different and no way is more correct, do what makes you happy imo

queen hinge
delicate delta
#

oh the book does say how to do the mult lighting and I was doing it wrong

#

the light each contribute a percentage of the total based on the number of sources

#

maybe that will fix what I saw

#

that seems to have fixed it

#

nah it's still wrong

#

this is like an inverted normal problem I think

#

yeah it is

#

so it is coordinate system related

#

my cross product is pointing in the wrong direction

#

told you

#

imagine having a normal right handed Y up

#

this is easy to fix though

#

it's a problem with top and bottom surfaces

#

it's weird that the winding order is correct but the normal isn't, when it's correct for both for the other surfaces

#

what does it mean

queen hinge
#
float ioDA = 3+5/(2-4*3+2)+5**2/2 int idAK = 4**ioDA List<T instanceof Object> list = new List<T instanceof Object>() ioDA += 4.0f idAK += 4i long uv = 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 { int ix = 0 if (a = 5 + 6) { List<?> lv = new List<>(i) if (a = 5 + 6) ix = 5 int 8ie = 5 }}int aTest = ioDR += 5 for (int i = 0 i < 100 i++) {} tfc.ralux.util.List<?> li = new List<tfc.ralux.core.String>()```imagine needing new lines or statement terminators
delicate delta
#

but why

queen hinge
#

my parser happens to be smart enough to actually not need any kind of line terminators
and my semi_truck was broken, so it didn't actually validate whether or not there were ;s

queen hinge
#

I wonder if any of the skills you gain from your sinister finger gun coordinate system actually is applicable for anything KEKW

delicate delta
#

honestly it might be even harmful

#

I think there's an issue with my light direction

queen hinge
#

maybe there's an actual reason people don't use sinister finger gun coordinate system that isn't just it happens to be thee case that people don't

delicate delta
#

I'm looking at my other book and it does lighting totally different

#

it does not offset multiple lights by multiplying it by a fraction of the whole for each

#

and it has the light direction in model space

queen hinge
delicate delta
#

    vec3 V = normalize(-v_matrix[3].xyz - varyingVertPos);
#

this code from the book is sus

#

it's taking the camera position there by taking the view matrix

elder kettle
#

That should be ok although I would not have done it this way

#

is it lighting in model space?

delicate delta
#

no

#

the lighting is in world space for me

#

but

#

I'm not sure that's my camera coordinates in world space

#

I should just confirm it is

#

which I can via renderdoc

#

        pub fn updateMVP(self: *Self) void {
            self.view_m = math.matrix.cameraInverse(self.camera_matrix);
            self.updatePrograms();
        }

        pub fn updatePrograms(self: *Self) void {
            if (!self.emit_matrix) return;
            for (self.view_uniforms.items) |prog| {
                prog.setUniformMatrix(self.view_m);
            }
            for (self.perspective_uniforms.items) |prog| {
                prog.setUniformMatrix(self.persp_m);
            }
            self.scene.updateCamera();
        }
#

this is how I set my view matrix

#
self.view_m = math.matrix.cameraInverse(self.camera_matrix);
#
pub inline fn cameraInverse(m: matrix) matrix {
    var r: matrix = .{
        .columns = .{
            .{
                at(m, 0, 0),
                at(m, 0, 1),
                at(m, 0, 2),
                0,
            },
            .{
                at(m, 1, 0),
                at(m, 1, 1),
                at(m, 1, 2),
                0,
            },
            .{
                at(m, 2, 0),
                at(m, 2, 1),
                at(m, 2, 2),
                0,
            },
            .{ 0, 0, 0, 0 },
        },
    };
    var vPos: vector.vec4 = vector.negate(transformVector(r, m.columns[3]));
    vPos[3] = 1;
    r.columns[3] = vPos;
    return r;
}
#

is mat4()[3] a column vector or row vector I have to go look it up

#

I'm just going to transpose it and see if that fixes it :X

#

and then look it up if it doesn't

#

ok

#

I have confirmed that vec3 V = normalize(-v_matrix[3].xyz - varyingVertPos); is correct

#

so that's not the issue

#

that brings me back to L

#

the problem is cosPhi 100%

elder kettle
#

make sure your sign conventions match

#

e.g. if your normal vector points out then your L vector should go from surface towards the light too

#

not from the light

queen hinge
#

cosPhi?

delicate delta
#

I am about to defenestrate the coordinate system it's wasting my time

elder kettle
#

Can you share an example of a normal vector and light direction vector that's misbehaving

delicate delta
#

share how? via a renderdoc capture?

#

or a screenshot? or some code?

elder kettle
#

just the vector values

delicate delta
#

sure

#
    light position: -0.155,    -1.046,    1.885        normals: 0, -0.5, 0
#

you can ignore the middle ones

#

they are the second light

elder kettle
#

what is it supposed to look like, it looks kind of strange overall

delicate delta
#

I put it far away

#

well the specular should be on the other side right

#

the specular should be reflecting toward the viewer

#

not away from the viewer

#

that white spot on the surface is on the wrong side of the red ball

#

the thing that's strange is that my torus is correct

#

but every other object is incorrect

#

including the normals I get from obj

#

which means my torus is incorrect and something else is incorrect and two wrongs are making my torus correct

#

I spent all this time working with just my torus and thought I had it all working

#

see how the specular is on the other side

#

but I just figured out that it depends on my viewing positions

#

I can make it not work for the torus too

#

so it's definitely a coordinate system issue

#

oh

#

I think it's a bug in my code actually now

#

anyway sorry to spam this thread I was just thinking outloud

elder kettle
#

that's what the thread is for haha

#

it does look like that

delicate delta
#

I think there's just a number of bugs, and that's one of them

#

I'll knock that one out though, that one seems obvious and easy to reproduce

#
pub fn updateCamera(_: *Lighting) void {}

I made this handler for my scenes to update stuff when the camera moves and I didn't implement it for this scene

#

hrm

#

nsight graphics is amazing

elder kettle
#

How is this different from renderdoc

#

seems the same to me

delicate delta
#

I don't have to click around as much

#

oh

#

maybe this is a problem with how I have my windows configured in renderdoc

elder kettle
#

Isn't it just two clicks to see the pipeline inputs in RD

#

Pipeline State > Vertex Shader

delicate delta
#

so before I set it up to look like this

#

the uniforms were on a different screen

elder kettle
#

Idk I just use the default setup

#

I don't often use uniform variables and UBOs though

#

Normally I am visualizing buffers

queen hinge
#

I think you’re the one in charge of how much you spam it for the most part, lol

delicate delta
#

ok

#

so I can reproduce this in the gouraud shader

#

I disabled everything but specular

#

the cube is in origin so effectively world space and local space are the same

#

and because it's the gauraud shader and a simple cube

#

I can just do the math on one vertex

#

it's clear that the color is 0, 0, 0

#

so now I can do the specular math and figure it out

#

it should currently be lighting up that corner

#

and it's not

delicate delta
#

yes

#

it was an x lh thing

#

the lighting happens in x lh

#

the view matrix is in y rh

#

I solved it by just setting a vec3 uniform with x lh camera position

#

7 hours

#

I spent 7 hours on that

#

it's fixed

#

TIL my camera space is RH y up

#

I have really nice lighting now though tbh

#

one bug I still have is my torus doesn't know when light is occluded

#

because it just goes by normals

#

I guess that gets fixed when I read about shadows

#

the inside of my cylinder is weird also because I don't want to make a second surface on the inside

delicate delta
queen hinge
delicate delta
# queen hinge Define?

The vertices I send for my cylinder are outside vertices. The winding order and normals are so that it it creates an an appearance as being surfaces of the cylinder you see that are when looking at it from outside

queen hinge
#

oh
You can add a thing to your shader to invert the normals on the backface

delicate delta
#

?

queen hinge
#

I think it’s gl_Backface for testing if it’s a backfacing triangle

delicate delta
#

Wouldn’t it have to be a separate surface on the inside

queen hinge
#

Nope, gl_FrontFacing

#

if (!gl_FrontFacing) normal*=-1; in frag shader

delicate delta
#

That’s cool

#

Thank you!

queen hinge
#

If you think the way you’re trying to do something is not good
Then you’re probably right, someone has probably already thought of it, and there’s probably already a solution

#

gl_FrontFacing is sorta rare to find in actual scenarios, since most of the time people don’t have cull facing off

delicate delta
#

Yeah the cylinder looks weird that way

#

The cone does too

#

I figured a proper mesh would have surfaces for both sides

#

Like if made it in blender instead of procedurally

#

I have to confirm my 3am finding regarding my camera space

#

That is really surprising, my fix does work

#

But my xup to yup is in the perspective matrix so I don’t understand what I was looking at. It was so late and I was do happy to have fixed the issue I didn’t interrogate it further

#

But I should understand it

queen hinge
delicate delta
#

I meant with cull facing enabled

#

Because you usually expect the visible inside surfaces of a cylinder to be visible in real life

queen hinge
#

Oh yeah
cull facing enabled will hide the back faces

#

So you just wouldn’t be able to see the cylinder from the inside

delicate delta
#

Right so I had it disabled

queen hinge
#

Yep

delicate delta
#

And that was fine until lightning made it weird

#

Appreciate your suggestion for a fix that doesn’t involve having to build both surfaces

#

Which is just like a one line change too and nbd I guess

maiden gazelle
#

That's cute

delicate delta
#

It’s an autobiography

maiden gazelle
#

Is it out-dated by now, or are the ideas still apply? Not that I'll watch it now, but I'm asking if I should add it to my "watch later" list

#

Solid approach to game design 👍

#

Nice! Stuff's coming along nicely

maiden gazelle
maiden gazelle
delicate delta
#

You’re catching up on a week’s scrollback rn lol

maiden gazelle
#

Yeah it's a bad habit of mine

#

It's probably annoying to be at the other end of these replies 😅

delicate delta
#

It’s np

maiden gazelle
#

I'll try not to

delicate delta
#

No worries

maiden gazelle
#

I played some God of War Ragnarok and I see you made good progress in the meantime

#

Time to study then

ivory verge
#

2 of them are novideo sites, linked in the topic of #opengl

#

and the other one, look for the pins, find marttys pin from the top, there are either one or two pdfs? or pptxes linked

#

thats what you need

maiden gazelle
#

Thanks!

delicate delta
#

ok

#

my camera space is not in Y up RH

#
[0.51, 0.86, 0.00, 0.00]
[-0.54, 0.32, 0.78, 0.00]
[0.67, -0.40, 0.63, 0.00]
[27.49, 69.31, 7.44, 1.00]
#

is my view matrix

#
[-73.60, -13.31, 4.56]
#

is my camera position

#

it's Y up though

#

That was from nsight, this is renderdoc:

v_matrix {0.9981, -0.04566, 0.04139, -0.44095}
{0.06163, 0.73954, -0.67029, 12.00697}
{0.00, 0.67157, 0.74095, 9.26029}
{0.00, 0.00, 0.00, 1.00}    float4x4 (column_major)

camera position

f_camera_pos -0.29988, -15.11862, 1.20501    float3
#

from renderdoc it just looks like there's a loss of precision in the third column after inverse transform the camera position/orientation to generate the look at between he view matrix and the camera position

#

nsight however just looks totally different

ivory verge
#

you need to select the right draw call

#

in rdc and nsight

delicate delta
#

I can't tell in nsight

ivory verge
#

in rdc you have swapbuffers selected

delicate delta
#

in renderdoc it gives me the instance count

ivory verge
#

in nsight you have an eevnt list too

delicate delta
#

yeah I'll just get more familiar with nsight

ivory verge
#

this thing

#

you select the glDrawXX there as well

#

for those the uniforms and whatever state is the one you need to check

delicate delta
#

it should be the same per frame

ivory verge
#

still

delicate delta
#

so I don't think picking the draw call should matter, but the events view is cool

#

I can see the actual uniform event

ivory verge
#

you select the clear, draw or dispatch events - the latter two are the most important ones

#

everything else doesnt matter

#

and go from there

delicate delta
#

dispatch is swapbuffers?

#

I don't see a dispatch

#

ah

#

there

#

[-134.90, -16.00, 3.00] is my camera position

#

[134.90, 15.93, 3.35, 1.00] is row 3 of my view matrix

#

there it's x up thank god the world makes sense

#

it's just the inverse I have fucks it up so lighting ends up broken

#

if I try to just negate it

#

pub inline fn cameraInverse(m: matrix) matrix {
    var r: matrix = .{
        .columns = .{
            .{
                at(m, 0, 0),
                at(m, 0, 1),
                at(m, 0, 2),
                0,
            },
            .{
                at(m, 1, 0),
                at(m, 1, 1),
                at(m, 1, 2),
                0,
            },
            .{
                at(m, 2, 0),
                at(m, 2, 1),
                at(m, 2, 2),
                0,
            },
            .{ 0, 0, 0, 0 },
        },
    };
    var vPos: vector.vec4 = vector.negate(transformVector(r, m.columns[3]));
    vPos[3] = 1;
    r.columns[3] = vPos;
    return r;
}
#

var vPos: vector.vec4 = vector.negate(transformVector(r, m.columns[3]));

#

that's the thing

#

I bet it works if I inverse the 3x3 of my view matrix and transform the negated third colum

#

but I think I'll just pass my camera position separately

#

anyway my lighting is boss, I love it now

#

I shoudln't have tried to keep working on this so late

#

I just really wanted to understand it

#

I do now though

#

so glad my camera space is x up, xup rules I have figured it out and that's the end of x up issues forever the end

#

my normals, my winding order, my matrices, they all work, everything works

ivory verge
delicate delta
#

ah

#

nsights is cool

#

I'm going to stop sending my view matrix and just send my camera position

#

and just have a MVP

ivory verge
#

i send them individually, or at least m and vp, for more advanced isms later down the road you most likely need them separate like that

#

but yeah, you can always refactor and add/remove whatever you need later

delicate delta
delicate delta
#

vertex shading

#

you do the lighting in the vertex shader and send a color to frag

#

it gets interpolated

delicate delta
#

lighting with a texture

#

just a directional light

ivory verge
#

makes a huge difference neh/

delicate delta
#

I think so

#

one more scene update and I'm done with this lighting chapter

#

I gotta travel for work this week so will not be doing anything other than reading, I'm just going to take the vulkan programming guide and read it when I have time

elder kettle
#

I wouldn't take that step yet lol

delicate delta
#

Just going to read it for fun

#

Christmas time I am hopeful to be done with opengl book and will migrate

elder kettle
#

I thought you were going to make a game

delicate delta
#

I am

#

You can make games with Vulkan

#

OoenGL is over it’s like abandoned

elder kettle
#

In theory but I have never observed evidence of it irl

#

Nobody here who has switched their game project to Vulkan has survived

#

It's just such a drag on productivity and if you don't really need it then it doesn't offer hardly any benefit

delicate delta
#

Vulkan Shader Objects is similar to OpenGL I read

#

It’s a new thing

elder kettle
#

Even with modern Vk it's still just death by a thousand cuts

#

If you want to recover the productivity of OpenGL you basically need to write your own OpenGL with Vulkan which is what your GL driver already does

#

My recommendation is to at least write a Vulkan-style renderer with GL first and then learn Vulkan from there rather than trying to learn them both at once

delicate delta
#

Well if it turns out to be unproductive and a waste of time i can just backtrack

elder kettle
#

True I suppose

#

You should still do some MDI rendering at the bare minimum though

#

it will make Vulkan make a lot more sense

ivory verge
#

the 2 links in #opengl's topic are the least thing to do before vk

delicate delta
#

as another alternative

delicate delta
#

ok I put my view matrix back into the thing

#

I also made it a UBO for that

#
layout(std140, binding = 0) uniform CameraBuffer {
    mat4 f_mvp;
    mat4 v_matrix;
    vec4 f_camera_pos;
};
#

I'm going to put global lighting in there too tbh

queen hinge
#

me when I interpreted UBO as undefined behavior object

delicate delta
#

I hardly have UB anymore

#

I can't remember the last time I had UB tbh

#

early on with zig and opengl I had a ton

queen hinge
#

my favorite undefined behavior is rendering an vertex buffer object that doesn't exist

delicate delta
#

heh

#

it's kind of hard with my engine to have UB because it's so scene based, with blockens I had this long running game that just had a global state with multi threaded job system and did a ton of stuff

queen hinge
#

meanwhile I'm rigging up intellij in ways it wasn't meant to be rigged up

delicate delta
#

with scenes I just allocate and deallocate each scenes resources

delicate delta
queen hinge
queen hinge
delicate delta
#

I'm going to avoid doing anything multithreaded for as long as I can

queen hinge
#

understandable

delicate delta
#

I think for big models I load them incrementally for a portion of each frame instead of just a blocking load, which is what I do now

queen hinge
#

bleakekw I made a like 5k line long file and duplicated a random line and now IJ seems to be frozen

delicate delta
#

intellij is actually really good with big files

#

I tested it once

#

opened a huge file in all the editors

#

and intellij was the only one that could syntax highlight the whole file with no problem

#

everything else froze, crashed or just showed no syntax highlighting

#

I don't remember how big the file was, it was very big

queen hinge
#

lol

delicate delta
#

it was a big json file iirc

queen hinge
#

ok so
with my plugin and my weird antlr rig up, file editing with a 5k line large file feels about as fast as editing a java file iirc

#

it's actually 5.6k lines

#

nope bleakekw

#

fair amount slower

#

probably because antlr allocates an entire object for every single parsed token
actually multiple objects
oh wait no
it's because antlr doesn't let me start the lexer at an arbitrary point in the file
I think
nope

delicate delta
#

idk what antlr is

queen hinge
#

antlr is a tool for creating parsers

#
grammar Statement;

import Arithmetic, Typing, Directive, Tokens;

statement_list: (body|flow|(directive|(SEMI SEMI*)|(statement semi_truck)))*;
body: '{' statement_list '}';

statement: call | definition | assignment | directive| ret;

// return
ret: RETURN expr;

// control flow
flow: if|loop|special|label;
loop: label* (for|while|do);

special: ((BREAK WORD?)|(CONTINUE WORD?)) state_end;
state_end: (SEMI|NL);
label: WORD ':';

// do
do: DO body while_header;

// while loop
while: while_header (body|(statement+semi_truck));
while_header: WHILE '(' (expr) ')';

// if
if: IF '(' (expr) ')' (body|(statement+semi_truck));

// for loop
for: FOR '(' (loop_enhanced|loop_standard) ')' (body|(statement+semi_truck));
loop_enhanced: (full_type? WORD ':' expr);
loop_standard: ((statement?) semi_truck (expr) semi_truck (statement?));

//|'+='|'-='|'/='|'*='|'&='|'^='|'%='
definition: full_type WORD '=' expr;
assignment: (WORD operand expr)|(WORD dOperand);

// calls
call: method_call|ctor;
method_call: (named_type '.')? WORD '(' params ')';
ctor: NEW type '(' params ')';
params: (expr ',')*? expr?;

// operands
dOperand: INC_INC|DEC_DEC;
operand: EQUAL
       | PLUS_EQUAL|MINUS_EQUAL
       | DIV_EQUAL|MUL_EQUAL
       | MOD_EQUAL
;

semi_truck: ((SEMI SEMI*)|{inferSemicolons}?);
delicate delta
#

ooh that's cool

#

are you making a programing language too?

queen hinge
#

yep

#
public class ShortHand {
    protected static void test() {
        int i = 5 + 2 * 3.#;
        int hs = "Hello".#;
        String str0 = "Test";
        String str1 = "Test";
        if (str0 .= str1) {
            System.out.println(42);
        }
    }
}
```looks pretty similar to java
but tbf, java's syntax is sorta just *C's syntax but everything is an object*
delicate delta
#

how are you planning on managing memory

queen hinge
#

good question
planning to do a hybrid of scope tracking and GC

delicate delta
#

is it a compiled language or interpreted?

queen hinge
#

compiled

delicate delta
#

what does it compile to

queen hinge
#

well I don't have a compiler yet

#

plan is LLVM IR

#

745470600
279000
369300
wbhuh why is look ahead so slow

#

I should just get the lookahead values directly using reflection ig

delicate delta
#

don't lookahead

queen hinge
# delicate delta don't lookahead

not an option; I need to know how many tokens I have (because IJ for some freaking reason doesn't expose this information) and I need to know every token ahead of time to pass that off to ANTLR

#

o
ij does expose that
but only if you cast to a PsiBuilderImpl (for the token count)

#

289700
264800
1896500
lot more reasonable but still not great
I'll have to improve that more later 🤷
I know a few ways to do so already
(this is nanosecond execution duration for the three sections of code I decided to put timers on)

delicate delta
#

hrm

queen hinge
# queen hinge 289700 264800 1896500 lot more reasonable but still not great I'll have to impro...

Said things:

  • don’t copy the list of tokens; instead steal the array that backs the psi builder impl and put it into a helper class that extracts the token and acts as a List<Token> despite having a IElementType[]
  • don’t copy my parse tree to a tree node to then do the exact same logic I would do anyway KEKW
  • potentially hijack the generated antlr parser to output directly to the ij psi builder so I don’t have to iterate through the tree in the first place
queen hinge
# queen hinge *good question* planning to do a hybrid of scope tracking and GC

Scope tracking being basically
At compile time, analyze the lifetime of objects to see if it never leaves a "trackable scope" (defining scope, field of object from same scope that also doesn’t leave scope) and if so insert a destructor op
If it ends up outside of trackable scopes, then it’s the garbage collector’s problem unless it’s a manually managed object

delicate delta
#

yeah that makes sense

delicate delta
#

I should post my space shuttle thing here too

#

it's fun

maiden gazelle
queen hinge
delicate delta
#

I haven’t yet written any code for it but reading the Vulkan Programming Guide I actually don’t get how this slows development velocity. You set up the rendering pipeline once and now each new tasks is as much work as it would have been with GL?

ivory verge
#

its the amount of primitives (VkInfo1, VkInfo2, VkInfo3, ...) you have to deal with/keep in mind

queen hinge
ivory verge
#

for textures you need 3 or 4 things, texture, image, imageview, imageviewlayout or something

delicate delta
#

I don’t think that MDI is a big deal, but I also don’t see why learning that first before vulkan is suggested it has both direct and indirect instancing

ivory verge
#

vulkan pretty much is based on mdi

queen hinge
#

What is mdi

ivory verge
#

multi document interface 🙂

#

multi draw indirect

delicate delta
#

What does it mean it’s based on MDI?

queen hinge
ivory verge
#

if you make your gl renderer gpu driven, you have a simpler time lubing yourself into vk

#

no glUniformXX bs, just buffers, textures, samplers and programs, "compiled" into pipelines and "descriptor sets", and you store draw commands into a buffer too

delicate delta
#

Ah

ivory verge
#

the azdo talks talk about that

#

you pretty much want as little state change as possible, and let the gpu figure out what to draw (no more interaction between cpu and gpu, which is slow)

#

ofc there is still state you need to/can change dynamically (aka dynamic state) like viewport/scissor and other things

#

lets say you have a primitive renderer... which draws your meshes with textures, and you visualize boundingboxes with colored lines, and light sources with 2d sprites which show a light texture
then you can split that into 3 "pipelines"
where pipeline1 is setup so that it describes the vertex format for your meshes... pos/normal/uv, loads/compiles shaders for that, those shaders might contain some PBR stuff too
pipeline2 is super shrimple, no pbrisms, just handles vertex attributes pos/color
pipeline3 is pretty much the same, but doesnt handle color, just is used to draw a 2d sprite with a lamp texture on it, perhaps depth test is disabled for this one, or pipeline2 too so that you see bboxes and light sources across the whole map of yours in your editor

late jackal
ivory verge
#

no rogue glEnable(GL_CULL_FACE); glCullFace(GL_BACK); here and there at random spots

#

the 2 blog posts linked in #opengl's channel topic talk about that too, textures/samplers and bulkan's counterpart image/imageview/imagelayoutbs

#

regarding that "descriptor set" bs, i always thought of it as 'describe what buffer, texture is supposed to be bound at what binding' aka what you do with glBindBooferBase/glBindTextureUnit/glBindSampler etc - and it probably is exactly that, but does provide certain hints to the driver so that it can juggle shit around to be properly aligend or whatever the driver can use to optimize that thing

#

when lustri sees this, he will instantly tell you that descriptor sets bs are a thing of the past, but not really 😄 you still have to setup A mega descriptor of sorts

wise imp
#

the thing with vulkan is that you end up having to implenent a LOT of abstractions yourself

#

on igl you just do texture upload and leave it there

#

with vulkan now you need to think how to make a upload queue with some staging buffers looping and then hooking that into the game code and all that crap

#

and that goes for many features

delicate delta
#

I see, appreciate all the context. It’s just gotta be done. OpenGL is in maintenance mode and there’s Vulkan, Directx and Metal or some middle api like webgpu or bgfx

#

I am just going to do the work

#

I need hope and a future and OpenGL can’t offer that I don’t care if drivers will support it for some undetermined amount of time. It’s just not a concern with these other APIs like Vulkan

#

I figure he OpenGL mesa driver may factor into future OpenGL viability Again not anything you don’t have to worry about if you’re not using OpenGL

delicate delta
#

.

elder kettle
#

Lol

elder kettle
#

OpenGL will probably outlive all of us

#

OpenGL 1.0 will probably outlive Vulkan lol

#

If you want to learn Vulkan for fun then go for it but the fact that GL is frozen is not a sensible reason on its own to not use it

#

Games aren't the only things that run on OpenGL

#

Desktop applications of all sorts run on OpenGL

#

Really important desktop applications like SOLIDWORKS

#

And ubiquitous GUI frameworks like Qt

#

I am guessing QRhi defaults to OpenGL

#

In fact if anything Vulkan is the uncertain one, it seems very likely that Vulkan will continue to be maintained for quite some time but it's not really used much yet

#

Games almost all use DX11 or DX12

#

Desktop applications don't use Vulkan much yet afaik

#

So if anything DX12 is the best choice if you're basing this purely off of sheer future-proofness

#

But realistically there will be emulation layers that turn GL calls into Vulkan or DX12 or whatever calls so there is really no limit to the lifespan of these APIs

#

So even if you are really that concerned about your game being playable in 30 years it's still not a problem

#

If you are truly worried about future flexibility what you should be doing is focusing on completely opaque firewall-style abstraction techniques that allow for the complete excision of that code without touching anything else

#

Because that way even if all current graphics APIs are wiped from existence, you can just delete your current renderer and write a new one without touching any of your application code

#

This is very hard if you are trying to make the renderer generic but quite easy if you are willing to make the renderer bespoke for your game

#

In the game and engine layer, your state is all completely abstract from a graphical standpoint, and just gets passed to a render(scene) function that the game knows nothing about

#

And then the renderer is free to just use the API directly to render the application

#

If you put your abstraction in that location then you could literally render the game in a GL context and Vulkan context simultaneously without to change anything in the game

#

Or have a runtime switch between them

#

This does require more work because the renderer implementation will require more "frontend" code than it otherwise would (interpretation of the application state) but it's much less work overall

#

And leaves you freer to use advanced techniques without fighting your own abstractions

#

In fact in my opinion the superior way of learning Vulkan is to do so by porting an existing GL application to Vulkan

#

Doing that is how I developed this philosophy in the first place, I was porting my game that was such a pile of shit codebase that I just wrote the renderer to passively consume game state and directly interpret it which ended up being extremely effective, I didn't touch a single line of game code except to comment out my old render() function and put in my new one

#

The reason MDI is good practice is because it prepares you for the fact that Vulkan doesn't provide you an apparent synchronicity with the GPU like GL does

#

In GL you can upload buffer data, draw, upload buffer data, draw, and it will just work, whereas in Vulkan that would result in UB and/or completely stall the device

#

MDI is good practice for having to organize all your draw data up front, it forces you to get into the Vulkan mindset of preparing your scene data for asynchronous execution at some time in the future rather than relying on this illusion of synchronicity that GL provides you

#

Doing MDI with persistently-mapped draw and data buffers basically switches GL's memory model over to Vulkan's

#

The rest of the API will be familiar and you can still randomly change pipeline state (e.g. blending, culling, etc.) on the fly like you're used to, but now can focus on learning how to feed this new async pipeline and learn how this paradigm shift changes how you approach your renderer design

#

When you switch to Vulkan and have to do all this extra work to create your pipelines and memory allocations up front, it'll just be a matter of learning the API mechanics since you'll already understand generally how to approach it, which would not be clear if you're used to GL's synchronous API design

delicate delta
#

yes that makes sense, if you're already using those features especially

elder kettle
#

Also sorry for the wall of text I drank coffee this morning which is unusual for me and I'm listening to an Equinox track so my brain is going haywire

delicate delta
#

no it's no problem I appreciate the perspective

#

my own engine is using very few opengl features

#

it's just all instanced index draws

#

and some ubo and ssbo for simple data

#

nothing complex going on

#

would be over the top to do MDI, which you might point to as an argument against, and ask why Vulkan, to which my response is OpenGL is in maintenance mode and that's enough for me. Doing OpenGL MDI would just be uncessary busy work imo. I looked into it as part of blockens I know how it works.

elder kettle
#

Seems very backwards but suit yourself

#

If MDI is overkill then Vulkan is gigakill

#

The main reason to use Vulkan is because you have run out of knobs to turn in GL

#

The main practical reason, that is

#

again if you just want to use it for fun then so be it

delicate delta
#

you can point to me in the future as a you don't want to be this guy

#

:P

#

I appreciate your perspective

shy cosmos
#

welcome to the cool kids club

#

we have better tooling, better validation and better API

elder kettle
#

A deal with the devil

#

You get all those things but forfeit your ability to make games

queen hinge
#

so true

late jackal
#

Fake, I'm equally unproductive with both APIs

queen hinge
#

I'm equally unproductive with both APIs
opengl because I just stop abruptly, vulkan because I run into walls and code quality problems and also because random stopping

delicate delta
#

It’s just an API yall

#

Really

elder kettle
#

You'll find out

#

Vulkan is more than an API

#

It's a mindset

queen hinge
#

(I was not criticizing vulkan; I just sorta, don’t do things in a way that is good for using vulkan)
But yea vulkan requires… a whole other mindset than opengl, lol

#

Vulkan expects stuff to be rigidly defined
Opengl doesn’t really care
I tend to do a lot of prototyping, so I tend to prefer stuff being not rigidly defined because having to define things rigidly takes time and effort

#

In cases it’s worth the reward; but not really for my stuff

#

Of note; I’m also someone who will openly admit that opengl is a bad api
It’s a very easy api to pick up, but much like java, it’s built on a lot of deprecation and compatilayers

delicate delta
queen hinge
#

OpenGL is infact not a modern api
And the specification has stopped being maintained

delicate delta
#

Sign me up

queen hinge
#

It is however, still a viable solution for graphics tasks though

#

OpenGL drivers do a bunch of behind the scenes stuff that you don’t ask them to :P

delicate delta
#

It’s Vulkan 1.0 but this book is pretty great so far. I am just reading it while traveling and plan to revisit it when done with my OpenGL book and GEA and then go through all the more modern Vulkan books and VKguide

elder kettle
#

Vk1.0 is even more tedious than 1.3 but that's what I learned

#

everyone I've talked to here says I am a moron for not using 1.3

#

but 1.3 didn't exist when I learned vk lol

delicate delta
#

Yeah I plan on using 1.3

#

But powering through this book nonetheless

#

I read the first chapter and browsed quickly through all the pages of the book to get a sense of the API. Just going to continue to read it until I am back home and get back to GL then for a bit

#

I think I will just reboot my engine and start over on the rhi and remove my weird coordinate system when I switch and remove all the learning scenes I currently have when I start on vulkan. I will keep all the math and geometry and asset loading

#

I want the scenes to be external from the engine, as in a separate translation unit with extern using c api, not a hardcoded list I think, so the engine is reusable for multiple games

#

I think I will start with a simple snake game tbh

wise imp
#

i have that book and honestly i thought it was kind of terrible

#

basically just reworded spec

#

it was a day-1 released book to cash in on vulkan release, so it doesnt really contain good info, it was just done as a way to sanitize and explain a bit the spec

#

vulkan-tutorial is more useful than that

late jackal
#

excellent restraint

maiden gazelle
maiden gazelle
ivory verge
#

i probably omitted a lot of vkisms here and you should take my halfassedisms with a big chungus of a rock of salt

maiden gazelle
wild ember
wild ember
delicate delta
#

I'm not sure this has been productive

shy cosmos
#

it's ok you'll be productive after writing a nice abstraction for yourself

queen hinge
delicate delta
ivory verge
#

@delicate delta i cant dm you anymore?

#

im ok with it if you dont want me to anymore, i must have done something wrong

delicate delta
#

I just disabled server member dms

#

Should work now?

ivory verge
#

oh

zinc trail
delicate delta
#

I will just leave them on

zinc trail
#

I have them off in most servers. I only leave it on in ones that aren't filled with scammers

delicate delta
#

It’s just it buzzes my watch when I get a dm because it’s my primary way I talk with my daughter

#

She doesn’t sms she dms on discord gpAkkoShrug

zinc trail
#

Oh mines setup to never notifications. This is not the platform to reach me on if you want immediate feedback lmao

granite bolt
fleet dew
fleet dew
delicate delta
#

alright alright back from salt lake city time to get back into it

late jackal
#

are you a Mormon now

delicate delta
#

no, would take more than week for that I think

#

I was surprised by how small SLC was

#

it's tiny, the downtown area is like 5 blocks at most?

#

reminded me of Tucson

late jackal
#

nice

delicate delta
#

I saw a hockey game, with the new Utah Hockey team which doesn't have a name yet, that was fun

#

I was at the very top and it looked like a video game and I was thinking about how it would be to make a game with all the cool lighting in that stadium

late jackal
#

I presume it was at night then

delicate delta
#

it's indoors, but yes it was evening

#

time to make a sports game

#

probably not a lot of indie sports games, untapped market?

#

everyone is making minecraft and factorio clones

elder kettle
#

The standard these days is to make the game indistinguishable from watching TV on sports

#

You'd have to come up with your own unique spin on it

delicate delta
#

I think these probably require multiplayer and I don't ever want to make a multiplayer game

#

just seems like maybe a good market for an indie studio that doesn't get a lot of attention, but I could be mistaken

delicate delta
granite bolt
#

hello, master of the books, how is using Zig?

#

I was thinking of changing from using Rust, to either c3 or zig

delicate delta
#

I like it

granite bolt
delicate delta
#

c3 and zig are both pretty different than rust

#

but there's a lot of people who have written rust who use zig

#

I think c3 is probably going to be easier since it's more compatible with C

granite bolt
#

I wanted something like C, but with a modular approuch

#

and it seem that both c3 and zig does that

delicate delta
#

idk how mature c3 is compared to zig

#

zig has a lot of geniuses working on the compiler

granite bolt
#

well if it isnt horrible to use C libraries with zig

#

im actually sold

delicate delta
#

it can be

#

horrible

granite bolt
#

in what way?

delicate delta
#

like extensive use of macros, zig can't replicate it

#

a prime example is flecs

#

which has a ton of meta-programming

granite bolt
#

then I think it is fine. I was only thinking of terms of adding the Vulkan lib

delicate delta
#

C Translation makes a best-effort attempt to translate function-like macros into equivalent Zig functions. Since C macros operate at the level of lexical tokens, not all C macros can be translated to Zig. Macros that cannot be translated will be demoted to @compileError. Note that C code which uses macros will be translated without any additional issues (since Zig operates on the pre-processed source with macros expanded). It is merely the macros themselves which may not be translatable to Zig.

#

ah

#

vulkan is fine

granite bolt
#

then it is gucci

delicate delta
#

there are zig bindings for vulkan memory allocator

granite bolt
#

thank you for ur input. You created another zig user today 🫡

granite bolt
#

but other then that, I was thinking just using libraries fully written in zig

delicate delta
#

I don't use any zig libraries

#

it's horrible

granite bolt
#

wtf wait, why

#

💀

#

is the compiler not backward compatible or something?

delicate delta
#

the zig getting started guide suggests using zig nightly

#

no, it's not backwards compatible

#

and I download the compiler every day

#

and it's frequently breaking backwards compatibility

#

there's a stable version

#

and some libaries use pinned versions

#

but basically

#

I tried that and it wasn't any fun

granite bolt
#

ah, it is a horror

#

I will have to continue search

#

for a lang

delicate delta
#

projects frequently get abandoned

#

it's a lot of work to stay upto date

#

yeah

#

C++ is a good language I heard

granite bolt
#

I used that before, but then I would just go with Rust instead

#

but ty anyway 😄

delicate delta
#

C3 keeps compatibility

#

maybe try that,

granite bolt
#

I will do that

#

I just heard, it didnt fully support C, but maybe that is old news

queen hinge
delicate delta
#

None of these are popular

#

C3, nim and zig are tiny niche languages

delicate delta
#

shadowmaps gpAkkoShrug

queen hinge
#

What type of shadow map? KEKW

delicate delta
#

why is there something wrong with it?

#

I don't understand the kekws :P

#

are there different types? it's just a 1 pass framebuffer with a depth test and texture attachments

#

and then I sample it on 2nd pass

#

it's just what was in the book :\

#

I'm going to work on softening the shadow and then make it work with my two lights scene

queen hinge
#

There’s
a lot of methods of shadowmapping
Cascaded, distorted, virtual, probably more

delicate delta
#

ok I don't know what those things are, I didn't know what shadowmaps were yesterday

delicate delta
#

shadowmaps are kind of weird, if you have like a light in a center, with this approach you have like create 6 passes for that single light?

#

in all the directions

#

idk, my other books also have chapters on shadows

#

I'll learn more

ivory verge
#

yep for point lights you usually render the world 6 times, once per cardinal direction

zinc trail
#

my shadows have 4 cascades

delicate delta
#

what do you mean by cascades?

ivory verge
#

its basically your shadow viewfrustum

#

cut into sections

#

and rendered individually rather rendered as 1 big frustum

#

that will make your shadows look neat over some distance

#

since you lose shadow quality over distance quite kwikly

delicate delta
#

and this happens each frame for each light in each direction?

ivory verge
#

pretty much

zinc trail
#

it really helps with quality, since you can fit your shadow box tighter for closer stuff

delicate delta
#

I guess the fragment shader is a noop

ivory verge
#

you can optimize it and only redo them when the light or objects within the frustumses move

delicate delta
#

idk seems like a lot

zinc trail
#

a lot of the time you can just simply not provide a fragment shasder for shadow maps :p

delicate delta
#

mine is just an empty main function

ivory verge
#

yeah thats ok

delicate delta
#

I think gl requires a fragment shader

zinc trail
#

only the vertex shader is required

delicate delta
#

oh maybe it's different for depth pass

#

if you don't have a color attachment

ivory verge
#

yep

zinc trail
#

im pretty sure you get implmentation dependent stuff if you have a color attachment with a shader that doesnt write to it

ivory verge
#

its irrelevant

zinc trail
#

for shadowmaps yeah, you dont care about color anyways

delicate delta
#

I don't add a color attachment the book just had an empty frag shader so that's what I did

ivory verge
#

but if bjorn continues like that we will soon have an implementation of virtual shadowmaps 😛

#

the holy grail

zinc trail
#

i gotta dig into shadows more tbh

queen hinge
delicate delta
#

I feel like since I plan on making my levels and not procedurally generating and the levels are mostly static except for specific objects I can probably do a really good job with shadows

#

and lighting

queen hinge
#

If most of your geometry is static, you could probably bake a majority of the shadows

delicate delta
#

they're also going to be small levels for the most part

delicate delta
#

this is pretty interesting

#

I just set like a static light for my shadowmap

#

but this is making the argument to move the light position so that it's tight with the camera's view frustum

ivory verge
#
#
delicate delta
#

I noticed a small artifact along one of the edges of that block

#

it's in an area not included in the shadowmap

delicate delta
#

added a small amount of dithering/ PCF

#

idk

#

adding shadowmaps to my two light point scene is gonna be a bit harder, I need to rethink my code organization because I kind of hacked this together onto my dolphin scene

late jackal
#

have you tried using a shadow sampler?

#

they give you a little free pcf with bilinear filtering

delicate delta
#

I use a sampler2DShadow

#

but it was still a little blocky

late jackal
#

yeah with bilinear it'll still be kinda blocky so you need some sort of wide or stochastic filter

#

I'm a fan of using a hammersley sequence to generate samples on a disk

delicate delta
#

oh cool

#

thank you

#

I did a thing from my book that uses an offset pattern based on x and y position

late jackal
#

It has some defines you can play with

delicate delta
#

thank you! that looks great

#

ooh mode 3 looks cool

late jackal
#

Hammersley sequences have the nice property of having few voids and clusters, something white noise suffers from. In other words, you get a nice even sampling of the entire space

#

It's similar to blue noise in that regard

delicate delta
#

thank you, this is really useful and looks great

#

such a simple looking algorithm

late jackal
#

Ah yeah low discrepancy was the word I was looking for

#

Bayer matrices can also be used for dithering and sort-of "random" numbers that cover a space

#

I find random numbers fascinating

delicate delta
#

I already gawked at the one you were using in your ray tracing

#

the pseudo rng you were using

#

PCG

#

alright I think it will take me a while to add shadowmap logic to my 2 point light scene. I'm going to think about it. I kind of need to add attenuation to it too

late jackal
#

It solves a lot of problems that fract(sin()) stuff has

delicate delta
#

I'm going to get to some ray tracing at the end of this book, there's a couple of chapters, and the the next math chapter is a ray tracing chapter too

delicate delta
#

I'm going to start adding point shadowmaps to those tomorrow

#

and those objects can cast shadows on each other

late jackal
#

what shading model is that?

delicate delta
#

blinn phong

#

you mean light model?

#

I can select from those three up there in that list

late jackal
#

whatever "blinn phong" is categorized as, yeah

delicate delta
#

those are the only three I know right now 😅

late jackal
#

what UI library are you using?

delicate delta
#

this is a themed imgui

late jackal
#

Oh cool

delicate delta
#

it uses demon's theme, but I modified it a little

late jackal
#

Zig bindings for dear imgui?

delicate delta
#

no I use cimgui

late jackal
#

Ah

delicate delta
#

I don't have any zig dependencies

late jackal
#

How does that compare to c++ dear imgui

delicate delta
#

it's worse

#

but nearly identical

late jackal
#

Is it a fork that reimplements everything in c

delicate delta
#

it's generated from C++

late jackal
#

Oh huh

delicate delta
#

it's identical, just a weird C api

#

can't overload C

late jackal
#

hmm so a bit more verbose in places?

delicate delta
#

right, and required args

#

that are optional in dear imgui

late jackal
#

It's cool that you can use dear imgui basically anywhere now

late jackal
delicate delta
#

const pos = c.ImVec2_ImVec2_Float(vp.WorkPos.x + 50, vp.WorkPos.y + 50);

#

:P

#

it's gross

late jackal
#

You could make a wrapper for those annoying functions yourself, couldn't you

delicate delta
#

yes

late jackal
#

Does zig support default args

#

I used it once

delicate delta
#

no, well you can do it with struct parameters

late jackal
#

Ah, close enough

delicate delta
#

structs can have default values

late jackal
#

PBR is a giant rabbit hole as they say

delicate delta
#

I have a PBR book I will get to I hope next year

#

the PBR from theory to implementation book

#

real time rendering and some other books, a lot of books

maiden gazelle
#

Great now I gotta catch up (Shadows)

delicate delta
#

I think eventually I'm going to spin up an http and std.http.WebSocket server inside my engine to remove imgui, then I can control my engine remotely, outside of the game

#

via a browser

#

and other applications

wild ember
#

I think that might be cool, but I would leave ImGUI in there, its super useful to have controls right inside the engine

delicate delta
#

I might add an in game terminal with stb easy font

zinc trail
#

ive considered making my own gui library but i never bothered going very far since imgui exists

#

the most ive really done is getting "proper" text rendering

delicate delta
#

I am currently not interested personally in building a UI library

zinc trail
#

ive had experimental ones public but never did much with it

#

it handled multilang stuff decently well too

delicate delta
#

you used harfbuzz?

#

rendering text is the hardest part of any UI

zinc trail
#

thats the part i havnt gotten to work yet

#

but generally speaking a lot of languages already work, just certain scripts dont display as youd expect

delicate delta
#

you built your own text rendering?

#

what shapes the primitives you display? are you reading fonts? are you parsing fonts yourself?

zinc trail
#

i have a stb library to rasterize them for me but other than that everything is done by myself

queen hinge
#

Maybe I should do my own foundations sorta project KEKW

delicate delta
#

make a game

#

you already know all this stuff

#

I'm doing this because I don't know anything

queen hinge
#

I actually do not know all this stuff, believe it or not

#

Shadow map stuff I know, barely anything about

delicate delta
#

shadowmap is kind of a lot of work, compared to anything I've done so far

#

except the initial look at

queen hinge
#

I know a lot of the terminology, but I know next to nothing about the actual logic
I’ve done a rudimentary implementation, but nothing good for shadow mapping

delicate delta
#

I'm working on that right now, the dolphin shadow was just like my first ever attempt

queen hinge
#

And that alone is probably more than I’ve done

#

I also know nothing about implementing pbr materials

delicate delta
#

I don't either

#

I just know the basic ADS materials

#

which I just copied out of the book

#

claude generated some for me too

queen hinge
#

eh
you implemented specular
that’s more than I’ve ever done in that end of things

delicate delta
#

I'm just glad I'm doing this all in zig

#

for real

queen hinge
#

Maybe my next graphics adventure will be in my own language KEKW
that’d be neat

delicate delta
#

are you a student?

queen hinge
#

I am in college

delicate delta
#

are you studying something related to this?

queen hinge
#

I am studying computer science stuff, yeah
… unfortunately, I’m stuck in introductory sorta classes

delicate delta
#

yeah that sucks

queen hinge
#

One of my professors tried to teach us to use java’s finalize method to track the number of objects of a certain type
… the garbage collector does whatever the heck it wants, that’s a horrible method of tracking objects

#

finalize is also deprecated in J8
we’re on like J23 I think nowadays? bleakekw
finalize is still around but like, it is absolutely not the sorta thing you should be using

delicate delta
#

C++ destructor has a similar problem iirc, calls things out of order

#

yeah I don't like using those

#

another way zig wins

queen hinge
#

There’s no current alternative to finalize but like
if you’re writing code that relies on finalize you are objectively writing bad code in like 99% of circumstances with java

late jackal
#

c++ destructor is called in a deterministic order- the opposite of the order in which things were constructed

queen hinge
late jackal
#

it's always been like that

#

everything would break if it wasn't like that

delicate delta
late jackal
#

I think it's well-defined within each translation unit

#

yeah

delicate delta
#

I see, I was just going by what I had read in GEA

#

I haven't written much C++

late jackal
#

having static/global objects that refer to each other is kinda stinky anyway

delicate delta
#

it goes on to show another approach

#

and says that also isn't reliable

late jackal
#

the issue is that there is no defined order in which constructors will be called for globals in different translation units (.cpp files)

#

within a single translation unit, it's well-defined (things declared first will be constructed first and destroyed last)

delicate delta
#

ah

late jackal
#

here, it is a bad idea to do the meyer singleton or whatever where you initialize the object the first time the global getter is called

elder kettle
#

How to make a singleton: just make one instance of your class

late jackal
#

so GEA isn't exactly wrong in saying that it leads to unpredictability

delicate delta
#

yeah the end strategy the author advises is to just create all your things at the beginning in order, and then destroy them in order explicitly before exiting and not rely on constructor or destructors (across TUs I guess)

#

which is what I already do with zig since that's the zig way

late jackal
# delicate delta and says that also isn't reliable

tbh you could make all your globals be inited in a well-defined order with no dynamic allocation, but it requires making aligned storage and using placement new. plus, it's not like using dynamic allocation for a tiny handful of stuff at init time will even matter

delicate delta
#

I wrote a function to generate my view matrices for my shadow maps and forgot to call it facepalm it's just been UB

#

there we go

#

that looks right

#

now to generate 11 more!

delicate delta
#

I got 12

#

now I guess do shadows?

#

I used 12 framebuffers

#

I tried to use 1 and attach different textures but that didn't work

#

I should read the spec about that

#

anyway

elder kettle
#

I have an example somewhere, just a sec

#
uint32_t w = g_impostor.width;
uint32_t h = g_impostor.height;
using namespace engine::graphics;
TexParams params;
params.texParams = Texture::Parameters
{
    .format = Texture::Format::RGBA,
    .sourceFormat = Texture::SourceFormat::RGBA
};
Texture templateTex = create_texture(w, h, params, nullptr);
texture::initialize_tex(templateTex, g_impostor.color);
texture::initialize_tex(templateTex, g_impostor.normal);
g_impostor.depthStencil = framebuffer::create_depthstencil_renderbuffer(w, h);

glGenFramebuffers(1, &g_impostor.fbo.m_ID);
glBindFramebuffer(GL_FRAMEBUFFER, g_impostor.fbo.m_ID);

glFramebufferTexture2D(GL_FRAMEBUFFER,
    GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_impostor.color.m_ID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER,
    GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, g_impostor.normal.m_ID, 0);

glFramebufferRenderbuffer(GL_FRAMEBUFFER,
    GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, g_impostor.depthStencil.m_ID);

bool complete = (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
assert(complete);

// Set multiple render targets
GLenum drawBufs[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glNamedFramebufferDrawBuffers(g_impostor.fbo.m_ID, 2, drawBufs);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
#

This is from my impostor rendering

#

There are DSA versions of some of those functions I was just lazy and copied my existing code for them

delicate delta
#

oh I am doing a different pass for each texture right now

#

hrm

elder kettle
#

This is for multiple render targets

#

I'm not sure if it helps or not idk what the best way to render a bunch of different shadow maps is

#

rendering to layers of an array texture maybe

delicate delta
#

oh hrm that's interesting

#

I'm just kind of brute forcing my way through this scene atm

#

I'm writing some horrible GLSL right now too

#

I can make it better later

late jackal
#

glFramebufferTexture is a little bit better API than glFramebufferTexture2D

#

the only functions you should use are glFramebufferTextureLayer and glFramebufferTexture. But because of how glFramebufferTextureLayer doesn't work on non-array cubemap faces, you have to use glFramebufferTexture2D for faces of a non-array cubemap.

delicate delta
#

ok this is going to be some zig, sorry about that

name: c.GLuint = 0,

const FrameBuffer = @This();

pub const FrameBufferError = error{
    FramebufferIncomplete,
    FramebufferStatusCheckFailure,
};

pub fn init() FrameBuffer {
    var name: u32 = undefined;
    c.glCreateFramebuffers(1, @ptrCast(&name));
    return .{
        .name = name,
    };
}

pub fn deinit(self: FrameBuffer) void {
    c.glDeleteFramebuffers(1, &self.name);
}

pub fn setupForShadowMap(self: *FrameBuffer, depth_texture: Texture) FrameBufferError!void {
    self.attachDepthTexture(depth_texture);
    const buffers = [_]c.GLenum{c.GL_NONE};
    self.setDrawBuffers(&buffers);
    self.checkStatus() catch {
        return FrameBufferError.FramebufferStatusCheckFailure;
    };
}

pub fn setupForColorRendering(self: *FrameBuffer, color_texture: Texture) FrameBufferError!void {
    self.attachColorTexture(color_texture);
    const buffers = [_]c.GLenum{c.GL_COLOR_ATTACHMENT0};
    self.setDrawBuffers(&buffers);
    self.checkStatus() catch {
        return FrameBufferError.FramebufferStatusCheckFailure;
    };
}

pub fn setDrawBuffers(self: FrameBuffer, buffers: []const c.GLenum) void {
    c.glNamedFramebufferDrawBuffers(self.name, @intCast(buffers.len), buffers.ptr);
}

pub fn attachDepthTexture(self: *FrameBuffer, texture: Texture) void {
    c.glNamedFramebufferTexture(self.name, c.GL_DEPTH_ATTACHMENT, texture.name, 0);
}

pub fn detachDepthTexture(self: *FrameBuffer) void {
    c.glNamedFramebufferTexture(self.name, c.GL_DEPTH_ATTACHMENT, 0, 0);
}

pub fn attachColorTexture(self: *FrameBuffer, texture: Texture) void {
    c.glNamedFramebufferTexture(self.name, c.GL_COLOR_ATTACHMENT0, texture.name, 0);
}

pub fn checkStatus(self: FrameBuffer) FrameBufferError!void {
    const status = c.glCheckNamedFramebufferStatus(self.name, c.GL_FRAMEBUFFER);
    if (status != c.GL_FRAMEBUFFER_COMPLETE) {
        return FrameBufferError.FramebufferIncomplete;
    }
}

pub fn bind(self: FrameBuffer) void {
    c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.name);
    c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT);
}

pub fn unbind(_: FrameBuffer) void {
    c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
}

const std = @import("std");
const c = @import("../c.zig").c;
const Texture = @import("Texture.zig");
#

ohhh glFramebufferTextureLayer

#

I will look that up

#

detachDepthTexture was a mistake

late jackal
#

nvm you don't actually need the 2Dvariant ever, since DSA exists

glFramebufferTextureLayer may now be used on non-array cubemap faces, so now there is no point to any of the dimension-based FramebufferTexture functions

delicate delta
#

I shouldn't have included that in the paste

late jackal
#

once you get the hang of using framebuffers, you should try to ditch them asap (by wrapping them behind a friendlier "array of render targets" API)

delicate delta
#

thanks that sounds good

elder kettle
#

how do you select the right surface to render to then

late jackal
#

the api is BindSomeMfRenderTargets(listOfRenderTargets);

#

it's the same as vulkan when you use dynamic rendering

elder kettle
#

In GL terms though

late jackal
#

well you secretly use a framebuffer of course

#

I'm proposing wrapping them in a not terrible interface

elder kettle
#

ah ok