Getting deeper into the whole WBEM stuff, still not sure if any of this is really sane.
irb(main):290:0> puts c.enumerate 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PhysicalMemory'
CIM_PhysicalMemory:
BankLabel: "ChannelB"
Capacity: "8589934592"
CreationClassName: "CIM_PhysicalMemory"
ElementName: "Managed System Memory Chip"
FormFactor: "9"
Manufacturer: "Samsung"
MemoryType: "26"
PartNumber: "M378A1G43DB0-CPB "
SerialNumber: "317D4462"
Speed: "0"
Tag: "CIM_PhysicalMemory Tag"
CIM_PhysicalMemory:
BankLabel: "ChannelA"
Capacity: "8589934592"
CreationClassName: "CIM_PhysicalMemory"
ElementName: "Managed System Memory Chip"
FormFactor: "9"
Manufacturer: "Samsung"
MemoryType: "26"
PartNumber: "M378A1G43DB0-CPB "
SerialNumber: "3175C415"
Speed: "0"
Tag: " (#2)"
=> nil
Why are there end-of-line spaces in the part number AMT responds with?
Why is the second memory tag just a floating parentheses with "#2" in it?
Why isn't there an identifier on physical memory that I can use for retrieval? Like CIM_Fan? (And no, SerialNumber and BankLabel can't be used as selectors for that)
irb(main):291:0> puts c.enumerate 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Fan'
CIM_Fan:
ActiveCooling: "true"
CreationClassName: "CIM_Fan"
DesiredSpeed: "0"
DeviceID: "Fan 0"
ElementName: "Fan"
EnabledState: "5"
HealthState: "5"
OperationalStatus: "2"
RequestedState: "12"
SystemCreationClassName: "CIM_ComputerSystem"
SystemName: "ManagedSystem"
VariableSpeed: "false"
CIM_Fan:
ActiveCooling: "true"
CreationClassName: "CIM_Fan"
DesiredSpeed: "0"
DeviceID: "Fan 1"
ElementName: "Fan"
EnabledState: "5"
HealthState: "5"
OperationalStatus: "2"
RequestedState: "12"
SystemCreationClassName: "CIM_ComputerSystem"
SystemName: "ManagedSystem"
VariableSpeed: "false"
=> nil
irb(main):293:0> puts c.get 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Fan', selectors: { 'DeviceID' => 'Fan 0' }
CIM_Fan:
ActiveCooling: "true"
CreationClassName: "CIM_Fan"
DesiredSpeed: "0"
DeviceID: "Fan 0"
ElementName: "Fan"
EnabledState: "5"
HealthState: "5"
OperationalStatus: "2"
RequestedState: "12"
SystemCreationClassName: "CIM_ComputerSystem"
SystemName: "ManagedSystem"
VariableSpeed: "false"
=> nil
4.2 is the latest version that macOS supports, but there isn't that much useful stuff between 3.3 and 4.2, so you might as well pick 3.3
i'm using extensions for any features newer than 3.3, and maintaining a separate code path if the extension isn't supported
it's honestly bit of a pain to maintain separate code paths only because of macOS, but there's not much choice, other than rewriting your renderer to use Vulkan (MoltenVK) or adding a Metal renderer
When I first started programming, I programmed in FreeBASIC. All my programs were big jumbles of code and I didn't really understand OOP. Now, going back, it's such fun to program in because of the simplicity of the syntax and I now understand pointers, inheritance, other OOP stuff, etc. I also know more about the shell and how to use a compiler so instead of one gigantic file I have a multi-file project with headers, header guards, etc. and I'm just having so much fun in a really fun hobby language with a really helpful community
so it wouldn't be stupid if i just used 330? that's what I'm doing now. i realize it sounds conservative, but at the moment i haven't even moved to indexed buffers, still drawing raw tris, so additional ext and nv code paths seem like future additions if i wanted to pursue them
thanks for the advice, guys
Also I now know that I can write FreeBASIC bindings of C functions so I can write networking shit too (since it's not supported in FreeBASIC standard library).
working on that love compatibility layer
https://p4wqvg.dm.files.1drv.com/y4mYZgwIWLwQMRMGAFXsHi9QWjZ-eJWkjtRSU9DbjXJJxEVhXogWaYoAqzRxcIQb59pTdD2M229WojnR4EOICM46lUqrqy1bxjYw2PjdEtyGGRg8fQLgiPbqLUvLWhnBa3b9T_xq0nJJ6eD0ddTlHzArDPhvFIUh-F22zPXt3mtDgm-239Q5-Mfs3M7x8lFzB_dppHq3Dft0mvEfkDn5lAVAw?width=1920
i wrote up a nifty function that shows me where particular calls are that haven't been implemented yet, and I'm just running the game until i can get it to boot, implementing the functionality i need on the way
some stuff can be ignored, and i can write pass-through methods for now, and if i haven't written a pass-through function, the vm crashes and i can move along
since i still use the lua 5.1 module system, based on the behavior of modules specified in the reference manual, the love preloaded modules load on top of existing framework modules by aliasing the name over
which basically looks like
local module = modname or {}
_G.[ modname ] = module
in this case,
_G.love = framework
local module = framework.module or {}
-- This already exists.
-- _G[ framework.module ] = module
love.module == framework.module
i haven't looked into how the `local _M = {}` lua 5.2 idiom works with the package module, i assume those modules are cached, so in other versions, i'm sure you'd just grab whatever was in `package.loaded` or some other
More progress on my video editor. Haven't had as much time as before to work on it so progress hasn't been as fast as before.
Some changes since last post include audio playback, scaling media frame rate to project frame rate, scaling media resolution to project resolution.
https://streamable.com/qj7zf
amc, if you just want to make your game and are overhauling a major part of your engine already, why not switch to something "heavier"? Unity has been really productive for me and just looking at your content over the years, you're a better dev. Seems like the initial hump of learning an existing engine would be about the same inconvenience as redoing yours. I don't really know your motivations for doing what you do and I like watching it happen, but goddamn I've been waiting a long time to play your game.
you should mostly keep to ARB extensions, as those are usually the most widely supported (and the core functionality in newer opengl versions is solely ARB extensions)
there are some exceptions though, such as GL_EXT_texture_filter_anisotropic, which is available almost everywhere
Thanks, chimitos. I don't think I'm that great, though. I think that is clear by how long this has taken me. I think it's a series of time expensive decisions that held me back, plus being burnt by source and Half-Life 2: Sandbox hurt me to the point where I've most likely made irrational decisions like not just using Unity or Unreal.
Before I started dating and got married, I was working on multiplayer play testing with friends and Planimeter devs, and skooch/Lachlan Temple was managing the project. While he had great vision for how to get features out and move the game along, I was focused on the difficulties of development time. Things he wanted to prototype and ship took me too long to write. I'm notoriously slow, and I'm only just now stumbling on some tech that's been accelerating my speed, like leveraging LuaJIT's FFI to replace love, and Grid is developed enough where I'm fast on the engine and game layers, too.
Not having Chromium Embedded Framework around meant I was doing win32-like UI development for a majority of the game's development timeline, and learning that lesson cost me the most. This was by far the most expensive part of development. Removing the window-based user-interface would easily cut Grid in half, I'm sure (but I haven't confirmed the SLOC numbers).
The gui module in Grid is the largest module in the engine, and it's very much inspired by VGUI with its scheme system, which has also historically been counterproductive for developers. I blame myself as a user-interface designer for wanting the tools to make something look appealing enough for players to want to play around with, and developers to tool with.
At this point I've invested ~8 years in a system to compete with and replace LÖVE, Ivan Safrin's Polycode, and other LÖVE-likes and Lua-based game frameworks and engines. I've been heavily influenced by Source and GMod to the point where not using these systems means I'm changing my mental model to one based on blueprints or game engine IDEs that are rather foreign to me when I just want to make a game.
It would be another time expensive decision, which might not be a mistake, but I've made so many that I can probably only make a subset of mistakes now that are based on my current velocity that are more helpful than other decisions
All of this goes to say that I'm clearly really stupid, because in the time that I've been on FP, I've seen people build a lot more impressive tech and others ship games. I think I'm a very slow learner.
Reputation-wise, I've also probably closed doors that I should have remained silent to keep open, etc.
I'm within a month or so of getting back to multiplayer testing; there are lessons learned that I need to build on there, so I'm trying to tunnel-vision my way to making that progress.
There's a lot of stuff to say "no" to, and only a few things to say "yes" to, and out of the "yes" category, I'm trying to focus on a subset of that.
If you wanna go the easy route I'd just pick whatever new cards from 3 or so years ago supported.
Saw this on my news feed, a source of free pbr materials if anyone needs any.
CC0 Textures
They look like those tasty chocolates
https://files.facepunch.com/forum/upload/106992/5b4a5e71-af2a-453e-b377-7a111dcc613e/image.png
Honestly saw his post and thought it was called adbenture. Shoulda stuck with that name!
I just want to make a game.
Really liked how people used discord reactions to interact with bots, so I made a simple soundboard bot myself. The spirit of Dota 2 voice wheel lives on
https://files.facepunch.com/forum/upload/1239/c574b1b2-9bd9-4242-8709-3f2607447c42/2018-03-26_02-07-34.webm
This. It applies to everything with sufficient complexity, and I've run into this trap so many times. You have to start standing on the shoulders of giants, otherwise you will never reach the clouds.
Amc if you want to switch to Unity you can add me on Steam or preferably Telegram/Whatsapp and throw me any Unity or C# questions. Not sure about timezone difference though but I am willing to answer any question at all, been working with Unity for ages. I'm sure there are plenty of people that want to help here in general as well. The learning curve on Unity is really good, I don't think I can mention anything that even gets close. The thing with Unity is getting a bit confused about details like Start/Awake/Update/FixedUpdate and debugging that stuff, but that's when you can just ask
Or go for unreal engine with C++
Yes, and someone here can surely help with that as well. Very limited experience with that myself
My job is basically to develop the entire infrastructure around my company's cloud platform. Create the deployments when we sign up a new user, create their user group, sign them up on activedirectory, etc. (let me remind you I'm an intern)
My small bit of self expression here is the list of company names I use for my test accounts:
Pokecenter
Pewter Gym
Mondo Burger
Weyland Yutani Corporation
Zaibatsu Heavy Industries
Tyrell Corporation
Ultor Corporation
Kruger Holding
Pirandello Kruger
Silvine Systems
Callaghan Construction
Maya Media
Anansi Group
ignore my child molester rating, i clicked by accident and can't figure out how to remove it. i'm good with computer
Don't ignore my child molester rating
Child molester is the new programming king.
Duno, 20 years imprisonment?
Getting caught ;)
Been working on improving the API of ShaderTools: trying to use it made me realize it was sorely lacking. Did a bunch of work on it to make it suck less to use, and hopefully to make it behave better. Still need to find a way to retrieve / store compiled shader binaries instead of recompiling everytime, but that involves using std::experimental::filesystem to check file modification timestamps and comparing the binary's last mod time to the mod time of the source string. And that's not always possible when using generated shaders from my permutation generation system, so that'll be tough.
A few people mentioned enjoying longer detail posts, so hopefully you're ready for this one haha. Ratings always help, btw, to know if posts like these are worth making. I don't take not rating personally, but it's always nice to know that writing up textwalls isn't unwelcome if nothing else! I should probably write more posts for my site, tbh, to satisfy those urges. Anywho, the biggest single change to ShaderTools is not storing shader source strings or shader binaries in a map with the path as the key. This doesn't work in the case of generated shaders, and doesn't help me retrieve things like what stage a shader belongs to - vital for being able to compile things properly and to parse the generated binaries properly. So I defined a new structure for ShaderTools:
struct ST_API Shader {
Shader(const char* shader_path, const VkShaderStageFlagBits stages);
uint64_t ID;
VkShaderStageFlagBits GetStage() const noexcept;
bool operator==(const Shader& other) const noexcept {
return ID == other.ID;
}
};
So what "ID" now entails is the "stages" input to the constructor and the hash of the shader's path. The path hash is stored in the upper 32 bits, and the stages are stored in the lower 32 bits. This gives me a unique handle for maps and storage, and lets me store the stages. I also now require shaders submitted as source strings (vs telling me where to find the shader's source file) to include a name, which is used as the "path" for the hashing. I also started storing compiled binaries and raw source strings in "global" maps: I did some reading on static variable initialization in DLLs/static libraries to make sure this proceeds properly when someone uses this library, so it's at least done in a valid way.
Now, using this library to simplify Vulkan pipeline setup is much easier. I added a "ShaderGroup" class to VPSK that is designed to as a way to tie together different shaders that are used in the same pipeline - which is required, in order for me to be sure that any retrieved pipeline data is valid and includes ALL the descriptor bindings used. Creating a new group and adding objects to it is super simple:
ShaderGroup lighting(device.get());
fname = prefix + "Light.vert";
lighting.AddShader(fname.c_str());
fname = prefix + "Light.frag";
lighting.AddShader(fname.c_str());
shaderGroups.emplace("Lighting", lighting);
No need to call a parsing/setup function either, as the items we need to parse are retrieved once we call the relevant methods during pipeline setup. So now instead of always assuming what the vertex layout / input attributes are gonna be by using compiled-in constants like this:
PipelineStateInfo.VertexInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertex_t::attributeDescriptions.size());
PipelineStateInfo.VertexInfo.pVertexAttributeDescriptions = vertex_t::attributeDescriptions.data();
PipelineStateInfo.VertexInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(vertex_t::bindingDescriptions.size());
PipelineStateInfo.VertexInfo.pVertexBindingDescriptions = vertex_t::bindingDescriptions.data();
The code now isn't shorter, but it's no longer-compiled in and allows for more flexibility and a more data-driven design:
const auto& shader_group = shaderGroups.at("Clustered");
std::vector<VkVertexInputAttributeDescription> attributes = shader_group.GetVertexAttributes();
PipelineStateInfo.VertexInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributes.size());
PipelineStateInfo.VertexInfo.pVertexAttributeDescriptions = attributes.data();
Unfortunately there's not any real way for me to yet specify the vertex attribute bindings in this way: those are related to the VBOs being used to represent the mesh data. In my case, I use two so that the position data of a mesh is in a single buffer that's easier to frequently update, and all the extra attributes (UV, normal, tangent, etc) are in a separate buffer. I plan to eventually make this dynamic as well, but it's not something that is related to the shader code itself actually, and it can't be retrieved from the generated SPIR-V binaries. It's also made retrieving the "VkPipelineShaderStageCreateInfo" objects required to tell a VkPipeline what shaders it's actually using much easier, but that's not something particularly worth reviewing here. What's really got me excited is how descriptor bindings are handled. This was a lot of previously-fixed code that was a bit annoying to type and write out, as it looked something like this:
constexpr static VkShaderStageFlags vfc_flags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
constexpr static VkShaderStageFlags fc_flags = VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
frameDataLayout = std::make_unique<DescriptorSetLayout>(device.get());
frameDataLayout->AddDescriptorBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vfc_flags, 0);
frameDataLayout->AddDescriptorBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, fc_flags, 1);
frameDataLayout->AddDescriptorBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, fc_flags, 2);
A Descriptor Set Layout in Vulkan just describes what kind of resources we're using in our shaders, where they're bound, what stages they're used in, and what descriptor set they belong to (specified as another binding index). This is attached to a PipelineLayout object eventually, which is required to generate a graphics pipeline. Previously I had type out all of the above - which isn't bad in this case, but for the compute shader layout I had to specify 12 bindings and thats when it begins to suck. And if I edit my shaders, removing bindings, re-arranging them, or changing what type of descriptor object (lets say making a texel buffer a uniform buffer or something) is bound at an index, I have to make sure to change the relevant Descriptor Set Layout code too. Gross. So, now I don't give a shit about that. But it gets worse: set layouts are per descriptor set. So in the case of the above Shader group, it uses 3 descriptor sets requiring 3 set layouts. So any change to those shaders requires making changes to up to 3 set layouts D:
Now though, things are much much easier!
frameDataLayout = std::make_unique<DescriptorSetLayout>(device.get());
const std::vector<VkDescriptorSetLayoutBinding> layout_bindings = shader_group.GetSetLayoutBindings(0);
frameDataLayout->AddDescriptorBindings(layout_bindings);
Having 3 lines of code is about what I had previously, but the difference is much more drastic in the case of highly-complex descriptor sets. Additionally, it allows me to avoid unused bindings from the layout on a per-shader / pipeline basis - unused bindings still have some overhead, so this can potentially increase performance. If nothing else, I don't need to know anything about the type or quantity of resources I plan to use ahead of time. So, the full setup code for a pipeline layout is now the above plus:
const std::vector<VkPushConstantRange>& ranges = shader_group.GetPushConstantRanges();
mainPipelineLayout = std::make_unique<PipelineLayout>(device.get());
mainPipelineLayout->Create(ranges, { frameDataLayout->vkHandle(), objModelLayout->vkHandle(), computeDataLayout->vkHandle });
pipelineCreateInfo.pipelineLayout = mainPipelineLayout->vkHandle();
Welllllll thats probably more than enough for any of the poor saps reading this: but the tl;dr is that I'm trying to reduce the pain of Vulkan's pipelines (which have upsides, to be fair) by making things more data-driven, making my own code more robust and easy to use in the process. I could probably write another equally long post on my shader permutation generator too, as it plays really well with this whole system and I cannot imagine having one without the other. Next is moving pipeline flags and values to JSON, so that creating a new graphics pipeline is as simple as reading a JSON file with key flags/variables set
I was warned when I started my first job that you should really be careful about test messages and profanity. Shows up when you least expect it :P
Since this isn't a purely webdev thing I'm posting it here:
I am working on a racing simulation company, one of the things I wanted to have on the site (which I can't tell you what it's for yet) is a track map with all drivers and some telemetry, the architecture I'm going for is having a server daemon that manages the actual game servers, the daemon then sends information (gathered through the game's UDP API) to the web server (which is hendrix) over UDP, this information is then sent to the clients, which is then rendered using a Godot engine application (the one in the video)
I haven't been provided the final designs for it, so I am using a very terrible UI to test functionality, the godot app in the top right is running in a web browser:
https://www.youtube.com/watch?v=874MvVep4PA&feature=youtu.be
Thinking about getting into vulkan, feel like there are too many unknowns and gotchas and performance yuckies and underspecification that a lower level of control will make me feel more comfortable. That plus I feel like every OpenGL related app that I write (especially this last one, which was a school project due today) becomes an ugly mess that, unless I plan every feature from the start, has state leaking every which way. Any ideas @paindoc ? I'd want this to be a million year project that I can refine over time instead of every other GL project I've started that I get nauseated from working with after taking a month long break.
Sorry, you need to Log In to post a reply to this thread.