senpie

Here's a pretty picture, and although UE experts will experience an ick with the gazillion mistakes I have made, I am still very proud. To be honest it feels kinda off, that I can just drag and drop super fancy assets into a mammoth of a software and say I've made this scene. So I do not really feel proud. Furthermore, my laptop was burning the whole time, not to mention that the project actually crashed several times. Furthermore, on average I had 24fps on this scene, so I cannot imagine who they make this games for ( could be that I had to do a room size of a 12 football yards of optimization ). Well at least now I know the basics of UE, and can apply to jobs which require expert knowledge of UE5, with several AAA titles under my belt:) Overall assembling the scene took me more than an hour, probably two, so I put so(o)me effort...

Landscape scene from UE5

Yet another day I get reminded why I stayed away from the C++ ecosystem and commercially successful and industry-defining technologies made with it. That crap is slow and buggy. I am sure I will say different things when I get a beefier system, but the physical pain I felt while playing around in UE was unreal ba-dum-tss. It gets especially worse when you follow a tutorial from a guy who has this insane build, where he uses some fancy assets and runs some fancy scenes ( while recording everything in 1080p btw ) and gets a smooth experience, while you go through three crashes and several hours of compilation to load a single scene, which you later understand did not really need to try yourself. Anyway, I followed the tutorial and will be almost done with it by tomorrow and share a screenshot with you. However today, I learned how to get fancy assets and use them in my project to make fabulous landscapes running at ~23fps ( with everything else closed ). Nevertheless, I believe I would have read another 20 pages of the C++ book if I had not sat idle waiting for the project to compile. That's it for today see you tomorrow!

Nothing crazy for today either. Tried to repeat the steps described in the tutorial on my own, although sometimes looked at the tutorials too and kind of know how to use the landspace tool now. I have to say, that my laptop is burning and I hate that. Nevertheless, I found out about the megascans, which seem pretty cool and they are pretty detailed and high quality assets for UE users, that are free to use and you can just drag and drop them to get started. That's it for today, next is foliage tool.

More Unreal Engine today! Watched how to customize materials with a normal map, roughness, and metallic maps, and also how to create master material. As expected UE gives a lot of customizability achieved by exposing variables for quick tweaking. Next was one of the biggest strengths of UE 5, the Lumen lighting system, which allows for real-time global illumination and reflection and cool shadows. Also, the old way ( old doesn't mean bad in any way ) baking the light and shadow maps were presented. The guy also managed to explain the different types of lights within UE such as directional light, point light, cone light, and box light. Pretty standard stuff, so far. The next topic was terrain creation, which for now seems similar to what Unity has to offer. Today, it was only learning, but tomorrow I will probably instead try to replicate everything I've learned these two days from memory on my laptop and see how it goes. That's it for today, see you!

Nothing interesting for today, unfortunately, I finished the chapter and learned about “friends”. Although they seem useful they also seem excessive to me. After finishing the chapter, I opened up a Unreal Engine tutorial and watched part of it since it's very long. I learned the basics, like navigating the project, modifying the objects in the world, creating materials, copying files from different projects, and basic post-processing effects. That's it for today, see you!

Can C++ overload itself to be some other language like Rust or Oberon? More overload, the more my brain stops braining. The overloading syntax is not the hard part. It is however hard to foresee the consequences of your overloading and how the user is then supposed to properly use your design. This time I read about overloading increment and decrement operators, also overloading allocation ( new, new[] ) and deallocation ( delete, delete[] ) operators. Also, the user-defined literals were discussed in more detail, that is you can build new literals on top of the literals, that are already provided by language. Based on these tools, the author showed the simple implementation of std::string, with optimizations and a convenient interface. Of course, it doesn't come close to the original std::string, however, it was usable. I reached probably the most funny topics of the book called friends and finding friends, which I can see to be an up-to-date struggle for most C++ developers ( get a life ). I believe my brain needs a bit of rest from this book, so after I finish this chapter ( tomorrow ), I will for a couple of days switch to another topic, either to programming a basic but modern ray-tracer or to the basics of Unreal Engine, depends on how I will feel. That's it for today, see you!

Today I finished the chapter on operation overloading and started? that's right the chapter on operation overloading. Although, as much as it might confuse you ( it was indeed written in a way to confuse you ) the chapter I was reading before talked about logical operations and arithmetic operations overloading, however, the new chapter talks about special operators ( (), [], ->, ++, --, new, delete ), how to overload them, and how it has already been done for some classes, that are part of C++ standard. But before that, I should also mention that in the previous chapter, I learned about overloading a literal, which I think is quite useful. So, for example, you can define 123i, where i after the number would indicate would mean, that we want to construct a complex number complex{0, 123}, and it works. Another thing that you can override is implicit type conversion rules, so like if you have some user-defined type like Tiny, and you can say for example if we have function f(int) and we provide Tiny object instead, then how it would magically convert, that object to type int. That's also the part when my brain stopped braining. Now back to the topic of overloading special operators. One of the most notable ones is the overloaded subscripting operator. While in Java cringes, if you'd wanna access an element in ArrayList you would say a.get(i) and it's long and ugly, then in C++ you can access an element in vector ( the C++ counterpart of ArrayList ) with the beautiful syntax of v[i], because it is overloading const V& vector::operator[] (const K&) const and the other one ( lazy to type, sorry ). The function call operator overloading is also super cool, when you can call an object, it only has one method to execute and it will run it, with simple syntax obj(), which calls obj.exec(). Whereas in Java, if you'd write the Command Pattern, then you would manually call the obj.exec() which is ugly. The last topic I finished was dereferencing operator overloading, and it is the other topic that stopped my brain from braining. But I will not go into much detail, since you don't have to know about it anyways ( nor do I ). See you tomorrow, bye!

Today I learned about the concept of slicing, which is not really a thing in Java but exists in the realm of C++. It's when you copy an object B, but the pointer type is of its base A and only the part of A is getting copied, and members of B get left out. Sounds spooky to me, but the author assures that sometimes it's what the developer wants. Ways to prevent it is to either remove the copy constructor in the base class or make it private or protected so you will get an error. Then, the topic of move and copy semantics was discussed. Although it has been discussed in previous chapters already, this time it was more detailed. It also talked about the default behavior of compiler and how to prevent it, or otherwise make it more explicit. If you leave out constructor, copy, move, and destructor declarations, then the compiler will include default ones. You can get rid of it by using the =delete;, or if you want to explicitly show that default behavior is needed you can include =default;. Also, if you declare your own constructor, then the default will not be generated the same as in Java. Furthermore, if you declare a copy operation, move operation, or a destructor for a class, then no copy operation, move operation, or destructor is generated for that class. The book also talked about good practices for maintaining class invariants. However, this is something to be learned by experience, error, and trial. The next topic was operation overloading, but I will not bore you with that, since I believe it's quite boring to know the whole nitty-gritty details about it if you are not going to design your own library, but be a user instead. That's it for today, see you!

The chapter follows with more discussion on initialize_lists and constructors in classes. It covers cases, when ambiguity arises about which one to use, such as

struct X {
    X(initialized_list<int>);
    X();
    X(int);
}

X x0 {};    // empty list: default constructor or initializer-list constructor? (the default constructor )
X x1 {1};    // one integer; an int argument or a list of one element? ) the initializer-list constructor )

It also, reminds us of the correct use for initilizer_list, keeping in mind the values are immutable. The next topic was copy and move for classes. The terms of shallow and deep copy were discussed. The author also talked about the technique of combining the good of both worlds, that is 'copy-on-write'. It's fine for a state should be shared if it's immutable and used only for reading, however, nasty errors can occur if it's used for write. That's it for today, see you tomorrow!

Today's chapter was on constructors and destructors. It talked about why are constructors useful in establishing covariants, and destructors that do proper cleanup. Also, it talked about the order of their execution, that is constructor constructs in a top-down approach starting with the base class and destructor cleaning up from inside-out ( just don't forget the virtual). There are a few cases, where you would manually want to call the destructor, but usually, it will be called when the object gets out of scope. Furthermore, object initialization was discussed, where usually {} is almost always preferred over (), the only exception being vector and other used defined types where each has a different meaning. vector<int> a{10} means a vector with single integer value 10, whereas vector<int> a(10) would mean vector with ten integers all zeros. That's it for today, catch you later!