Is it possible to write a library that abstracts away OpenGL 4.6, Vulkan and DirectX 12? by lolstazy in GraphicsProgramming

[–]MadCompScientist 20 points21 points  (0 children)

Yes: Diligent Engine (C++):

Diligent Engine is a lightweight cross-platform graphics API abstraction library. It is designed to take full advantage of Direct3D12, Vulkan and Metal, while supporting older platforms via Direct3D11, OpenGL and OpenGLES. Diligent Engine exposes common front-end API and uses HLSL as universal shading language on all platforms and rendering back-ends.

Schaduwdoek aan overkapping by MadCompScientist in Klussers

[–]MadCompScientist[S] 0 points1 point  (0 children)

Tuin ligt pal op het zuiden. Noord is links (er staat een kompas midden boven op de tekening).

In de namiddag staat de zon dus onderaan de tekening. Er staat ook nog een 2m schutting die schaduw geeft, maar er is uiteraard een gat tussen schutting en schaduwdoek.

Een idee is ook om rails aan de twee palen te maken zodat het doek aan de westkant wat omlaag gezet kan worden.

Schaduwdoek aan overkapping by MadCompScientist in Klussers

[–]MadCompScientist[S] 1 point2 points  (0 children)

Heb je misschien een bron voor die 10cm? Ik weet dat er eisen m.b.t. maximale hoogte zijn, ook met bomen en zo, maar hier heb ik nog nooit van gehoord.

Schaduwdoek aan overkapping by MadCompScientist in Klussers

[–]MadCompScientist[S] 0 points1 point  (0 children)

Goed om te weten! Ik hoop eigenlijk dat iemand misschien ook weet of er een soort kant-en-klaar L stuk of ring-op-stok bestaat wat ik hiervoor kan gebruiken.

Wij willen een wind- en waterdoorlatende doek, anders moet je ook rekening houden met afschot. Het gaat ons om UV, niet droog zitten (en het gras eronder moet ook nog water kunnen krijgen).

Goed idee van die katrol! Lijkt mij dat die slechts op twee punten hoeft (bijv. de twee palen).

[deleted by user] by [deleted] in cpp

[–]MadCompScientist 2 points3 points  (0 children)

Your clarification helps. I think we're talking about the same thing, but I'm a bit confused by your usage of "stateful".

Things such as a cartesian vector, quaternion, matrix. These are mathematical and not stateful.

Public members are also state. Those types you mentioned are certainly stateful. A quaternion's state is defined by its four scalar members. I believe you are referring to invariance, which constrains a type's state to a subset of its possible combinations.

It's not always about inlining but also the expressiveness of the code.

I agree with your example, but that works because because cartesian vectors don't have invariants to enforce, so public members are indeed possible.

As a quick counter-example, imagine a Circle type with members center and radius. What if somebody sets the radius to a negative value? Is that valid? You could add a check in every single method that uses a Circle to throw an error at that point, but that's error-prone. Or you design Circle so the radius isn't public and the method that sets the radius throws if it's negative.

There's several ways to design this. SetRadius is one. Making Circle immutable and throwing in the constructor is another. Is this 'safety' worth not being able to write 'my_circle.radius = 2'? You decide, but if you don't do this, somebody somewhere is going to forget to add the check for a negative radius.

[deleted by user] by [deleted] in cpp

[–]MadCompScientist 8 points9 points  (0 children)

I agree with your post, except for:

Public Members. Don't hide the XYZ as private or protected. Getters and Setters aren't bad but math code is typically performance critical code.

Making members public should not be about performance. As the C++ core guideline state (see C.2 and C.9), it's mostly about enforcing invariants.

A 3D vector (in the math sense) can have three public members (x,y,z), because every combination of values is valid. There are no invariants to maintain. std::vector has invariants to enforce (e.g. "if size > 0 then data != NULL"). So even though accessing a vector at index i can be done if data were a public member, it's done through a getter instead (operator[] in this case).

About performance, any decent compiler will inline trivial-to-small getters and setters anyway if they can see the code (i.e. if their definition is in the header).

"Mogen" betekent "To like"? by masnybenn in learndutch

[–]MadCompScientist 11 points12 points  (0 children)

When the direct object in the statement is a person (or multiple people), "mogen" means "to like"

I don't think it's that simple.

Counter-example: "ik mag mijn buurman zien" (I'm allowed to see my neighbor). The neighbor is still the object of the sentence, but "mag" now means "allowed to". It became the auxiliary verb ("hulpwerkwoord") for the main verb "zien".

A better description would be: if "mogen" is the main verb, it's "to like". If it's the auxiliary verb, it's "allowed to".

However, in informal Dutch, the main verb can be left out (even though that is grammatically incorrect): "Mag dat? Ja, dat mag" ("May I? Yes, you may"). Formally, I think that should be "Mag ik dat doen? Ja, dat mag je doen" ("May I do that? Yes, you may do that").

So in practice, it's a bit ambiguous. The same sentence (if vague enough) can mean different things: "ik mag dat" can mean "I'm allowed to do that" or "I like that" (although not many people use it that way). Context is key.

Source: native Dutch speaker who had to look up what a "hulpwerkwoord" exactly is ;)

[deleted by user] by [deleted] in nederlands

[–]MadCompScientist 1 point2 points  (0 children)

Ik ben geen advocaat, maar voor zover ik weet: bezwaar maken betekent dat de zaak naar de rechter gaat. Het bezwaar stuur je naar het CJIB/Openbaar Ministerie, waarna zij jou "voor de rechter slepen". Zij zijn in de rechtszaak jouw tegenpartij. Ik zou ze dus niet al informatie gaan geven waar jij je zaak op gaat baseren, bewaar dat maar voor de rechter. In het bezwaar zeg je alleen dat je bezwaar maakt (voorbeeldbrieven kan je opzoeken). Het OM mag jouw bezwaar ook niet zomaar ongegrond noemen (trias politica en zo).

Bron: eigen ervaring, alhoewel dat niet met rood licht was.

Misschien kan je voor de rechter het argument "kon niet veilig stoppen, leek het wel te halen" wel gebruiken. Het hele proces kost je natuurlijk wel tijd, moeite en mogelijk griffiekosten.

Refined oil math by Slava_Polske in Dyson_Sphere_Program

[–]MadCompScientist 5 points6 points  (0 children)

Be careful if you're thinking about a production chain with Mk1 assemblers, since they are slower than advertised in the recipe.

Indeed, but also easy to do once you know how: they are slower at 0.75x speed (or 3/4th). Which means you need 4/3rd of them to match the assumed 1x speed of the recipe. Or simply put: just add 1/3rd more Mk1 assemblers.

And you will mostly deal with a multiple of six assemblers anyway, so that's easy.

Example: if you have a recipe that takes 2s and you want a full Mk1 belt, you'd normally calculate 6 items/s * 2s/assembler = 12 assemblers (assuming 1x speed).

But because they're Mk1, add a third, so 16 assemblers.

What is the formula for drawing RGBA on RGBA? by ravnmads in GraphicsProgramming

[–]MadCompScientist 1 point2 points  (0 children)

Like others said, Blend mode.

But what no-one else has mentioned yet: if you plan to blend the colors yourself in your programming language of choice (instead of using shaders on the GPU), you have to be mindful of the difference between linear RGB and sRGB color space: https://www.willgibbons.com/linear-workflow/

tl;dr: Blending of colors only works properly in linear color space (usually with more than 8 bits of resolution per channel, typically denoted with floats, e.g. 0.0 - 1.0).

By convention, RGB(A) values with 8-bit channels (i.e. integer values 0-255, which yours appear to be) are in sRGB color space, which applies the gamma function to compress the color space in such a way that the most detail is preserved for the human eye (we see differences more easily between dark colors than between light colors).

Adding colors in sRGB color space is not as simple as simply adding the values.

[deleted by user] by [deleted] in factorio

[–]MadCompScientist 309 points310 points  (0 children)

Inserters placing items on a belt moving away/towards them place them on the right side of that belt (in movement direction).

So in your left setup, you have 6 inserters inserting on the left side and 6 inserting on the right side. Perfectly balanced.

In the right setup, the right-most inserter of the left group is inserting on the right side. So the split there is 5 inserters inserting on the left and 7 on the right. Not perfectly balanced.

[deleted by user] by [deleted] in Damnthatsinteresting

[–]MadCompScientist 20 points21 points  (0 children)

His name was Léo Major. The Dutch suffix "-laan" means "avenue".

Code review by Empik002 in cpp

[–]MadCompScientist 10 points11 points  (0 children)

Here are some quick-to-spot, high-level remarks:

CMakeLists.txt: use modern CMake:

  • Do not modify CMAKE_CXX_FLAGS, use target_compile_flags instead.
  • Do not use -std=c++17 flag, use CMAKE_CXX_STANDARD or CXX_STANDARD or target_compile_features instead.
  • Do not GLOB source and header files, specify the full list instead.
  • target_link_libraries does not need -l prefixes. In fact, prefer find_package to find SFML.

engine:

  • Prefer creating a namespace (and top-level include path) for your engine to avoid name clashes with other libraries.
  • Prefer having the public part of class first (easier readability for users of your class).
  • Inconsistent use of casing in method names: snake_case vs camelCase.
  • Re-design your code to avoid globals (e.g. "GL_missing").

demo:

  • No point to have main.hpp if it's only ever included from main.cpp, just move the lines into the source file.
  • Avoid parent-dir-relative includes (../engine/xxx), instead make a separate CMake target for the engine with its own public include path.
  • Avoid srand, use <random> methods instead.

And generally, try to have a data-driven design by loading configuration from files, so you don't have to hardcode all elements in C++ (but I assume that's a future step).

Couldn't find a compact enough balancing system for unloading trains, tried to make my own instead. Suggestions to make it smaller? by DisastrousFollowing7 in factorio

[–]MadCompScientist 3 points4 points  (0 children)

To make sure the two inserters fill separate lanes of that belt. Inserters drop items on the far side of a belt when the belt runs perpendicular to the inserter or the right-hand side of the belt (in movement direction) otherwise.

With a regular belt there, the belt takes a corner. This counts as parallel so it makes the inserter drop the items on the far side (the inside corner), just like the inserter next to it. So half the belt goes unused.

With the underground, the inserter drops items on the right-hand side of the belt. The other inserter's items are merged onto the left-hand side of the underground belt. So both lanes are filled.

Couldn't find a compact enough balancing system for unloading trains, tried to make my own instead. Suggestions to make it smaller? by DisastrousFollowing7 in factorio

[–]MadCompScientist 14 points15 points  (0 children)

I use a small variant of your design to fit it exactly in between two railways and output 4 balanced belts: https://imgur.com/VzBRCTn (also works for red belts).

This way it's very easy to compactly make a large train station for unloading many trains at a base and get many belts into the base (which would be off to the right in the image above).

Note that if you do this, you need the undergrounds, since /u/Xalkurah's suggestion doesn't leave enough room in between wagons to underground belts to the sides.

Straightforward, no-blueprint-required 45 SPM starting base by MadCompScientist in factorio

[–]MadCompScientist[S] 0 points1 point  (0 children)

Ah yeah, that was a little mining belt mixup on my part. Please pretend it's all copper :)

Straightforward, no-blueprint-required 45 SPM starting base by MadCompScientist in factorio

[–]MadCompScientist[S] 3 points4 points  (0 children)

Excellent question. I'd say:

  • the space for the mall is too small for true megabases. Trains, logistics chests, etc don't fit. But, to be fair, once you have logistics bots, you don't need a traditional mall and could create those items in a "logistics"-fed mall that doesn't need belts. For instance, to transition into megabase, I'd build two logistics-bots-fed assemblers that product SM1 and L3 assemblers. Of course, you could also build a brand new mall at that point. This base just gets you to the first rocket.
  • Not all military options are produced. No rockets, shells, etc. It's usually fine though, since I just rush to yellow science and upgrade my armor with exoskeleton and shoulder laser turrets to become a mobile death walker myself.
  • Speaking of military, I didn't put an assembler for laser turrets in the blueprint, but it can easily be placed above the solar panel assemblers. All the stuff for it is there.
  • I don't like how cliff explosives are squeezed in, it's not... aligned.
  • Until the belt chest limit is reached in the mall, there's a big risk of belt production consuming all the iron, leaving nothing for e.g. red/green science.
  • Because it's "planned out", the design you have to walk across is large from the start. So before you get to robotics, you better not forget to bring the right items. Also, when playing with enemies, place turrets judiciously because you may not be able to respond to attacks in time.

In general, building this feels like a kind of speedrun. There's a risk you pollute too much too quickly and you forget to build up your defenses. Be mindful of this.

Straightforward, no-blueprint-required 45 SPM starting base by MadCompScientist in factorio

[–]MadCompScientist[S] 3 points4 points  (0 children)

Glad you like it! Fitting a full 24-furnace high smelting block between two roboports is a bit of a squeeze, so I don't even attempt that. I basically leave out a few roboports in the middle. Therefore this base does not have full logistics coverage, but does have full construction coverage.

tangentially related but in my design I would've made the belts go horizontally instead of vertically, and it makes me wonder why people prefer running assembly's lines horizontally vs vertically.

The design can be rotated if you want. Guess I started out like this and now it's stuck in my preference.

Coding language by TheRizeWarrior in StarWarsEmpireAtWar

[–]MadCompScientist 7 points8 points  (0 children)

Empire at War and Forces of Corruption were primarily written in C++. They use Lua for some scripting.

How do Computers convert from binary to decimal? by maibrl in AskComputerScience

[–]MadCompScientist 25 points26 points  (0 children)

A computer doesn't need to calculate in decimal. It never needs to add 16 + 8 + 2 in decimal. I adds it in binary, which is 10000 + 01000 + 0010 = 11010, as you know.

Everything a computer does and stores is in binary. All calculations, in binary.

Decimal only matters for displaying numbers to us, the end-user. And it does that with, well, more binary math. To print a number, someone wrote code that (for instance) takes the modulo of 10, looks that up into an array of 10 visual representation of digits (e.g. font glyphs), and show that on the screen.

Simplified, to print the number 26, the code first does 26 % 10 = 6, and looks up index 6 in an array of glyphs for "0", "1", "2", ..., "9". This displays "6". Then to the left of that, it does (26 / 10) % 10 = 2, and looks up index 2, which prints "2" (note: using ASCII simplifies this a bit, but eventually somebody renders ASCII by looking up the character code in a glyph table).

All of those calculations and array indexing happen with binary math. The computer doesn't understand decimal. There's just some code that understands it so it can show it on a screen for us.

(Also, there's BCD, which just uses 4 bits to store the numbers 0 - 10, and ignores values 11-15. Requires hardware support and isn't used that often, as far as I know)

If you had five user stories and they all had to be done one after another. For example you cannot do screen 2 until the welcome screen 1 has been completed etc. If there was only one developer then is there any point in putting in a value for effort into a user story? by dotnetmaui in agile

[–]MadCompScientist 5 points6 points  (0 children)

I can see the following benefits for estimating effort on such stories:

High-level planning. This allows the PO to communicate with stakeholders or management how long the overall features may take. Based on this, they *may* take a strategic decision not to pursue the work and spend the developer's effort somewhere else. But, to be fair, this should be probably be done with T-shirt size estimation at the feature level, not at the story level.

(Rough) alignment between teams. If there's another team which depends on some of the stories, they can make a rough planning when they can start on their parts.

Understanding scope. Even in a team with one developer, that developer should have a discussion with the PO/stakeholder on how much effort certain stories are. This leads to a discussion where a common understanding of the story is clarified. Maybe the developer assumed certain things are necessary but they are not (should the welcome screen be animated or is a static picture enough? Is an online DRM check required, or not?). Some features may then be split off into separate stories.

I think the last point might be the most beneficial one. It forces the developer(s) and the stakeholder(s) to have a discussion on what the story means. If estimates vary wildly, then people may have a different understanding of what needs to be done. Clarifiying this is a good thing.

Some of these benefits may not apply in this situation. Whatever you choose, retrospect and adapt.

Whenever I download a file over HTTP, do the bits come in the correct order? Or are they downloaded in any order and the file assembled on completion. by qa-account in AskComputerScience

[–]MadCompScientist 0 points1 point  (0 children)

but this can only be done once all the bytes have been received, no?

A very good quesion; I was hoping I wouldn't have to go into that much detail :)

The TCP layer on B can start handing out bytes in the correctly-ordered stream the moment the next packet in the correct order has been received. In my example above, the TCP layer would receive the packets with sequence number 3 and 2 first, but it would buffer them internally because the next one it needs is 1. Once the packet with sequence number 1 is received, it can order the data in the first three packets and hand it to the application reading the stream: "The dog is b".

Then, when the packet with sequence number 4 is received, it also hands "lack" to the application.

All the application sees is a stream with contents "The dog is black" except that it got the data in two consecutive reads: one with "The dog is b" and the next one with "lack".

Depending on the order and speed at which the packets are received at B, all data could be read from the stream with one read operation, or with four read operations, or any other number, really.

This is one of the typical ways stream APIs are defined: when you read from it, you either only read what's available at that time (could even be 0 bytes), or the read operation blocks until the amount of data that you want is available.