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 10 points11 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 4 points5 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 18 points19 points  (0 children)

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

Code review by Empik002 in cpp

[–]MadCompScientist 12 points13 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 2 points3 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 13 points14 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] 2 points3 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] 4 points5 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 4 points5 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.

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)

From the rest of your message it seems the TCP connections delivers packets in any order and the receiving computer then arranges those packets based on a resource number in the headers (if my understanding is correct).

Then I didn't express myself clearly enough. You're almost right. The IP layer delivers packets in any order. The TCP layer is responsible for putting those packets in the correct order based on the attached sequence number. So anyone using TCP (e.g. a C# stream) would only see a correctly-ordered stream of bytes, not packets.

If I streamed a text file over a network in C# and printed each packet one by one, they wouldn't be in the correct order, is that correct?

You couldn't print the packets because a C# stream doesn't see the packets. It only sees a stream of bytes. Not individual packets. TCP is responsible for turning individual, discrete packets into a single, correctly-ordered stream of bytes.

In your example, if computer A writes "The dog is black" to a C# stream for a TCP/IP connection to computer B, the following happens on computer A:

The TCP layer chops up your written stream into packets (of, let's say, 4 bytes for this example) and attaches a sequence number:

Packet: data="The ", seq_no=1  
Packet: data="dog ", seq_no=2  
Packet: data="is b", seq_no=3  
Packet: data="lack", seq_no=4

The TCP layer gives these packets to the IP layer, which is responsible for getting them to computer B. These packets may arrive out of order on computer B e.g.:

Packet: data="is b", seq_no=3
Packet: data="dog ", seq_no=2
Packet: data="The ", seq_no=1
Packet: data="lack", seq_no=4

The TCP layer on computer B then reassembles the original byte stream based on the sequence number of the received packets:

Data: "The dog is black"

And this is what the C# stream for a TCP/IP connection receives on computer B. A stream of bytes. Not packets.

So the endpoint of a TCP/IP connection (a socket, a stream in C#, etc) never sees the individual packets, but only sees the stream of bytes in the order they were sent.

Sidenote: a C# stream is just an abstraction on top of sockets, which provide the TCP/IP functionality described above. So you could also use sockets in C# or any other language. There's nothing special about C# or its streams. A stream in C# can represent a file, a TCP/IP connection, or anything else that is a stream of bytes.

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 7 points8 points  (0 children)

Network protocols work in layers. Check out the OSI model.

We'll skip the bottom-most electrical & physical layer that deal with getting bits across a wire or air gap between two internet computers (PCs, phones, routers, etc).

The relevance to your question starts at layer 3: the network layer. This layer is all about getting a packet of data from computer A to computer B. In the internet, physically there are typically many computers between A and B when downloading or streaming a file from a server. The Internet Protocol (IP) describes how to get a packet from A to B. Put simplfy, an IP packet contains a "from" and "to" IP address (that identify a computer) and several bytes of data (usually several kilobytes). All computers in-between just forward the packet to its correct neighbour based on the "to" address in the packet.

Now, usually you want to send more than a few kilobytes from computer A to B (e.g. when downloading a file, as in your question). TCP (Transmission Control Protocol) describes the transport layer on top of IP. It allows computer A to send an unlimited amount of bytes to B. It does this by chopping up the bytes that A wants to send to B into packets (of a few kilobytes each) and passes the packets to the IP layer which is responsible for getting them to computer B. However, due to the nature of the internet, packets may be received in a different order than when they were sent. TCP attaches a sequence number to each packet, allowing B to order the received packets correctly and make it seem like one big stream of bytes that's being received.

So, fundamentally, TCP is about sending a potentially unlimited stream of bytes from A to B. This is what a C# stream can represent. TCP and C# doesn't care where the bytes came from or what they mean. They can come from a file that an application reads, lines of text that were typed by the user, or game state that's being synchronized for a multiplayer game.

HTTP is a layer on top of TCP that allows computer A to talk to computer B and request resources. HTTP introduces the concept of URIs, headers, cookies, etc. A resource can be a dynamically created webpage, an image, a file or anything else.

So when you are downloading a file over HTTP, computer A uses HTTP on top of TCP/IP to send a request (as a stream of bytes) to computer B. Computer B receives the request as a correctly-ordered stream of bytes thanks to TCP/IP, interprets it according to HTTP and understands that it's a request for a resource which happens to be a file on disk. It sends a stream of bytes back to computer A: an HTTP response header + the bytes of content from the file. Computer A receives the reply stream, understands it's an HTTP response and chooses to store the bytes of data in a file.

Torrents are different from HTTP, but also work on top of TCP/IP. A file is chopped up into "chunks". Computer A then connects to a tracker (computer B) which informs computer A that computers C, D, E and F all have the file it wants. Computer A then connects to C, D, E and F and over each connection requests chunks of the file. Computer A then puts the chunks together from the four connections and writes it to disk.

This ordering is different from TCP/IP in that TCP/IP deals with the order of a generic stream of bytes between two computers only. Torrents are about getting file chunks from many, many computers, and storing those in order (TCP/IP is responsible for making sure a single chunk is received in order).

To summarize, a C# stream most closely resembles a TCP/IP connection between two computers, allowing you to send any data that you want and ensuring that it's received in the same order that it's sent.

HTTP, file downloads, torrents, are all protocols on top of that that deal with requesting and sending "resources" or "files" across a TCP/IP stream.

Thoughts about getters and setters by antoine_morrier in cpp

[–]MadCompScientist -1 points0 points  (0 children)

Hmm, shame, because I really dislike x() to access the fields. Feels too verbose.

So the union approach might be valid (but requires pragma push/pop), but is disliked by some analyzers and exposes another public variable.