#Foundations - Learning Graphics Programming with the Zig Programming language
1 messages ¡ Page 5 of 1
it's better than default
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
I can share the cfg tomorrow if you want to try it
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
The greens are from the user code not part of the theme
oh
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
I'll paste it here tomorrow if I remember I'm in bed now so don't have access to it
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
Solar system? 
Just for the sake of making one or is it for a sun ephemeris system or something
it's in the book
it's just the sun, the earth, and a moon
and a space shuttle now
Ah ok so a little space scene
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
yes I remember that
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
it was pretty cool, this one is just a toy
multiple lights
What resolution are you running
4k
width=3840;
height=2400;
The offsets and stuff must be interpreted as pixels
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
i wonder how Iosevka SS02 would look like in imgui
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
ah yes
spleens
what are otf
Ah I see now there's no shadow width option just a hard-coded 1px shadow and shadow color
hrm no I applied scale to what was there
Ah
scale blurs ze fonts somehow
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 };
but you can modify that when you addfontfromfilething where you tell it what fontsize you want
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
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
Also yesterday I tried NSight Graphics and wow it's fantastic
added a model picker, with a dolphin
ok next is just a directional light with a dolphin with its texture, and then the solar system work
this seems weird though
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
yea that's not right
imma guess specular is incorrectly applying to backfaces for some reason?
đ
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
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

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
you will (probably) fall off this train eventually -- would advise sometimes taking breaks
you have read programming books though
true
I have an equally high stack of books I was planning on reading sitting abandoned now though
my living room table has stacks of books which i want(ed) to read :3
ya'll wanted to read books?
my whole life
I've never really wanted to read books
still don't 
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
im only into science fiction and i used to read universe/quantum mechanics related stuff
tiny bit of fantasy
I love biographies
Read Greg Egan
i have robert silverberg to finish first
and the other dude's stuff, hard science fiction
Illustrations for Schild's Ladder by Greg Egan
vernor vinge and KSR are my favorite scifi authors
His books have like online diagrams and notes to explain the physics concepts lol
Illustrations for Schild's Ladder by Greg Egan
i wanted to go study quantum mechanics back when i was a kid
I read about the delayed-choice quantum eraser once and thought it was cool, but I know I don't understand any of it
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
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
Well it's the same spooky behavior as any other distributed entanglement problem
I don't understand any of it
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
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)
what does local realism mean?
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
Interesting
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
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
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
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.
lucky
I am a machine
<- 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
That's not a problem
Set several goals and then procrastinate on one by doing another
We are all different and no way is more correct, do what makes you happy imo
can't; I'll choose option xoajsudhihwoeahaojd out of a list that only goes up to option d

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
ok it wasn't bugging me but now it is
this is like an inverted normal problem I think
yeah it is
it's not a lighting bug it's a geometry bug with the parallelopiped
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

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
but why
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
also I would not have figured that out if I had originally written it wrong
I wonder if any of the skills you gain from your sinister finger gun coordinate system actually is applicable for anything 
honestly it might be even harmful
I think there's an issue with my light direction
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
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
that sounds kinda derpy
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
That should be ok although I would not have done it this way
is it lighting in model space?
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%
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
cosPhi?
I am about to defenestrate the coordinate system it's wasting my time
Can you share an example of a normal vector and light direction vector that's misbehaving
just the vector values
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
what is it supposed to look like, it looks kind of strange overall
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
it looks like the light direction isn't getting updated when I move
anyway sorry to spam this thread I was just thinking outloud
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
I don't have to click around as much
oh
maybe this is a problem with how I have my windows configured in renderdoc
Isn't it just two clicks to see the pipeline inputs in RD
Pipeline State > Vertex Shader
so before I set it up to look like this
the uniforms were on a different screen
Idk I just use the default setup
I don't often use uniform variables and UBOs though
Normally I am visualizing buffers
I mean itâs quite literally your thread 
I think youâre the one in charge of how much you spam it for the most part, lol
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
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
Yea thatâs not a bug, thatâs a lack of shadow mapping
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
oh
You can add a thing to your shader to invert the normals on the backface
?
I think itâs gl_Backface for testing if itâs a backfacing triangle
Wouldnât it have to be a separate surface on the inside
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
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
Oh, really?
I meant with cull facing enabled
Because you usually expect the visible inside surfaces of a cylinder to be visible in real life
Oh yeah
cull facing enabled will hide the back faces
So you just wouldnât be able to see the cylinder from the inside
Right so I had it disabled
Yep
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
That's cute
Itâs an autobiography
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
You know what you should do? You should get some cubes and arrange a ritua... nvm someone else prob did it
Creme caramel?
Youâre catching up on a weekâs scrollback rn lol
Yeah it's a bad habit of mine
It's probably annoying to be at the other end of these replies đ
Itâs np
I'll try not to
No worries
I played some God of War Ragnarok and I see you made good progress in the meantime
Time to study then
still applies, but you can also just read 3 powerpoints.
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
Thanks!
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
I can't tell in nsight
in rdc you have swapbuffers selected
in renderdoc it gives me the instance count
in nsight you have an eevnt list too
yeah I'll just get more familiar with nsight
this thing
you select the glDrawXX there as well
for those the uniforms and whatever state is the one you need to check
it should be the same per frame
still
so I don't think picking the draw call should matter, but the events view is cool
I can see the actual uniform event
you select the clear, draw or dispatch events - the latter two are the most important ones
everything else doesnt matter
and go from there
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
dispatch is compute stuff glDispatchxxx
ah
nsights is cool
I'm going to stop sending my view matrix and just send my camera position
and just have a MVP
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
gl_FrontFacing is problematic, it's only available in the fragment shader so doesn't help with gouraud shading and adds an if statement. the correct solution is just to have a mesh with the correct surfaces but I don't care enough about the cylinder, any time I actually use it the insides will not be visible
gouraud shading?
vertex shading
you do the lighting in the vertex shader and send a color to frag
it gets interpolated
makes a huge difference neh/
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
I wouldn't take that step yet lol
Just going to read it for fun
Christmas time I am hopeful to be done with opengl book and will migrate
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
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
Well if it turns out to be unproductive and a waste of time i can just backtrack
True I suppose
You should still do some MDI rendering at the bare minimum though
it will make Vulkan make a lot more sense
the 2 links in #opengl's topic are the least thing to do before vk
maybe you can also suggest people migrate to Olive.c in the topic
as another alternative
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
me when I interpreted UBO as undefined behavior object
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
my favorite undefined behavior is rendering an vertex buffer object that doesn't exist
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
meanwhile I'm rigging up intellij in ways it wasn't meant to be rigged up
with scenes I just allocate and deallocate each scenes resources
that's how you're supposed to use it
⨠threading â¨
is a great way to lose your mind sometimes
I just rigged ANTLR up to the lexer and parser definition systems 
intellij and ANTLR were not built to work together 
I'm going to avoid doing anything multithreaded for as long as I can
understandable
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
I made a like 5k line long file and duplicated a random line and now IJ seems to be frozen
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
lol
it was a big json file iirc
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 
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
idk what antlr is
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}?);
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*
how are you planning on managing memory
good question
planning to do a hybrid of scope tracking and GC
is it a compiled language or interpreted?
compiled
what does it compile to
well I don't have a compiler yet
plan is LLVM IR
745470600
279000
369300
why is look ahead so slow
I should just get the lookahead values directly using reflection ig
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)
hrm
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

- 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
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
yeah that makes sense
That's so cool
after 2/3 things, it can deal with a 22k line file with a reasonable speed 
nvm
actually part of that is PSI viewer tbf
trying the same with java froze IJ 
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?
its the amount of primitives (VkInfo1, VkInfo2, VkInfo3, ...) you have to deal with/keep in mind
Not quite â GLâs pipeline stuff is extremely dynamic, and vulkanâs pipeline stuff is very fixed
Also thereâs a bunch of other things to deal with
for textures you need 3 or 4 things, texture, image, imageview, imageviewlayout or something
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
vulkan pretty much is based on mdi
What is mdi
What does it mean itâs based on MDI?
Ah
Thought you were talking about some weird graphics interface that Iâve never heard of 
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
Ah
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

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
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
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
Lol
"specialized?" This is just word salad lol
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
yes that makes sense, if you're already using those features especially
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
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.
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
you can point to me in the future as a you don't want to be this guy
:P
I appreciate your perspective
welcome to the cool kids club
we have better tooling, better validation and better API
A deal with the devil
You get all those things but forfeit your ability to make games
Fake, I'm equally unproductive with both APIs
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
(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
OpenGL is infact not a modern api
And the specification has stopped being maintained
Sign me up
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
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
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
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
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
excellent restraint
I gasped for a second there
This is a perfect explanation. I immediately understand and I know next to nothing on VK pipelines in general.
Ouch
i probably omitted a lot of vkisms here and you should take my halfassedisms with a big chungus of a rock of salt
That wall of text is invaluable to many like myself so thank you
Did we really ever have that ability to begin with 
What about vkguide.dev 
I'm not sure this has been productive
it's ok you'll be productive after writing a nice abstraction for yourself
Can confirm; vk 1.3 is less annoying
I wasn't referring to my progress with vulkan
@delicate delta i cant dm you anymore?
im ok with it if you dont want me to anymore, i must have done something wrong
I was getting spammed
I just disabled server member dms
Should work now?
oh
Story of my life on discord.
I will just leave them on
I have them off in most servers. I only leave it on in ones that aren't filled with scammers
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 
Oh mines setup to never notifications. This is not the platform to reach me on if you want immediate feedback lmao
Damn, times has changed đ´
haha, I made my mom(43) install discord and we've been using it for chatting
thanks a lot, you answered some of the questions I had in mind
alright alright back from salt lake city time to get back into it
are you a Mormon now
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
nice
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
I presume it was at night then
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
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
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
I improved my previously very bad textured lighting
hello, master of the books, how is using Zig?
I was thinking of changing from using Rust, to either c3 or zig
I like it
ok im sold
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
I wanted something like C, but with a modular approuch
and it seem that both c3 and zig does that
idk how mature c3 is compared to zig
zig has a lot of geniuses working on the compiler
in what way?
like extensive use of macros, zig can't replicate it
a prime example is flecs
which has a ton of meta-programming
then I think it is fine. I was only thinking of terms of adding the Vulkan lib
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
then it is gucci
there are zig bindings for vulkan memory allocator
thank you for ur input. You created another zig user today đŤĄ
oh right, that one is important too đ
but other then that, I was thinking just using libraries fully written in zig
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
projects frequently get abandoned
it's a lot of work to stay upto date
yeah
C++ is a good language I heard
Nimâs a nice one, but not very popular
What type of shadow map? 
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
Thereâs
a lot of methods of shadowmapping
Cascaded, distorted, virtual, probably more
ok I don't know what those things are, I didn't know what shadowmaps were yesterday
Parallel splits
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
yep for point lights you usually render the world 6 times, once per cardinal direction
my shadows have 4 cascades
what do you mean by cascades?
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
and this happens each frame for each light in each direction?
pretty much
it really helps with quality, since you can fit your shadow box tighter for closer stuff
I guess the fragment shader is a noop
you can optimize it and only redo them when the light or objects within the frustumses move
idk seems like a lot
a lot of the time you can just simply not provide a fragment shasder for shadow maps :p
mine is just an empty main function
yeah thats ok
I think gl requires a fragment shader
only the vertex shader is required
yep
im pretty sure you get implmentation dependent stuff if you have a color attachment with a shader that doesnt write to it
its irrelevant
for shadowmaps yeah, you dont care about color anyways
I don't add a color attachment the book just had an empty frag shader so that's what I did
but if bjorn continues like that we will soon have an implementation of virtual shadowmaps đ
the holy grail
i gotta dig into shadows more tbh
Yep
You could do dual paraboild instead, which makes it 2 passes but lower quality shadows
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
If most of your geometry is static, you could probably bake a majority of the shadows
they're also going to be small levels for the most part
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
A little over a year ago I was looking to overhaul our shadow rendering at work in order to improve overall quality, as well as simplify the workflow for the lighting artists (tweaking biases all day isnât fun for anybody). After doing yet another round of research into modern shadow mapping techniques, I decided to do what I usually do and star...
Update 1/24/2016: one of the authors of the Moment Shadow Mapping paper contacted to let me know that there was an issue in my implementation of the 16-bit variant of EVSM. My sample app was clamping the maximum exponential warp factor to 10.0, which can result in overflow for a 16-bit float. This has the effect of reducing light bleeding, but i...
I noticed a small artifact along one of the edges of that block
it's in an area not included in the shadowmap
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
have you tried using a shadow sampler?
they give you a little free pcf with bilinear filtering
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
oh cool
thank you
I did a thing from my book that uses an offset pattern based on x and y position
Here's a little demo I made
https://www.shadertoy.com/view/7ssfWN
It has some defines you can play with
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
I'm reading https://en.wikipedia.org/wiki/Low-discrepancy_sequence now
thank you, this is really useful and looks great
such a simple looking algorithm
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
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
my beloved
It solves a lot of problems that fract(sin()) stuff has
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
added light attenuation
I'm going to start adding point shadowmaps to those tomorrow
and those objects can cast shadows on each other
what shading model is that?
blinn phong
you mean light model?
I can select from those three up there in that list
whatever "blinn phong" is categorized as, yeah
those are the only three I know right now đ
what UI library are you using?
this is a themed imgui
Oh cool
it uses demon's theme, but I modified it a little
Zig bindings for dear imgui?
no I use cimgui
Ah
I don't have any zig dependencies
How does that compare to c++ dear imgui
Is it a fork that reimplements everything in c
it's generated from C++
Oh huh
hmm so a bit more verbose in places?
It's cool that you can use dear imgui basically anywhere now
True those save a lot of typing
const pos = c.ImVec2_ImVec2_Float(vp.WorkPos.x + 50, vp.WorkPos.y + 50);
:P
it's gross
You could make a wrapper for those annoying functions yourself, couldn't you
yes
no, well you can do it with struct parameters
Ah, close enough
structs can have default values
the other popular ones are super complicated in comparison, so I think you're fine with these. A lot of games shipped with them anyway
PBR is a giant rabbit hole as they say
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
Blegh
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
I think that might be cool, but I would leave ImGUI in there, its super useful to have controls right inside the engine
I might add an in game terminal with stb easy font
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
I am currently not interested personally in building a UI library
ive had experimental ones public but never did much with it
it handled multilang stuff decently well too
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
you built your own text rendering?
what shapes the primitives you display? are you reading fonts? are you parsing fonts yourself?
i have a stb library to rasterize them for me but other than that everything is done by myself
Maybe I should do my own foundations sorta project 
make a game
you already know all this stuff
I'm doing this because I don't know anything
I actually do not know all this stuff, believe it or not
Shadow map stuff I know, barely anything about
shadowmap is kind of a lot of work, compared to anything I've done so far
except the initial look at
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
I'm working on that right now, the dolphin shadow was just like my first ever attempt
And that alone is probably more than Iâve done

I also know nothing about implementing pbr materials
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
eh
you implemented specular
thatâs more than Iâve ever done in that end of things
Maybe my next graphics adventure will be in my own language 
thatâd be neat
are you a student?
I am in college
are you studying something related to this?
I am studying computer science stuff, yeah
⌠unfortunately, Iâm stuck in introductory sorta classes
yeah that sucks
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? 
finalize is still around but like, it is absolutely not the sorta thing you should be using
C++ destructor has a similar problem iirc, calls things out of order
yeah I don't like using those
another way zig wins
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
c++ destructor is called in a deterministic order- the opposite of the order in which things were constructed
is that a new change?
Thatâs actually a pretty neat ordering 
what about global and static class instances?
having static/global objects that refer to each other is kinda stinky anyway
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)
ah
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
How to make a singleton: just make one instance of your class
so GEA isn't exactly wrong in saying that it leads to unpredictability
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
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
I wrote a function to generate my view matrices for my shadow maps and forgot to call it
it's just been UB
there we go
that looks right
now to generate 11 more!
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
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
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
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
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.
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
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
I shouldn't have included that in the paste
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)
thanks that sounds good
do tell
how do you select the right surface to render to then
the api is BindSomeMfRenderTargets(listOfRenderTargets);
it's the same as vulkan when you use dynamic rendering
In GL terms though
well you secretly use a framebuffer of course
I'm proposing wrapping them in a not terrible interface
ah ok


why is look ahead so slow