Writing a BATCH RENDERER in ONE HOUR!

  Рет қаралды 44,292

The Cherno

The Cherno

4 жыл бұрын

Go to www.hostinger.com/cherno and use code "cherno" to get up to 91% OFF yearly web hosting plans. Succeed faster!
Patreon ► / thecherno
Instagram ► / thecherno
Code ► Coming Soon!
Twitter ► / thecherno
Discord ► thecherno.com/discord
This video is sponsored by Hostinger.

Пікірлер: 99
@TheCherno
@TheCherno 4 жыл бұрын
Thanks for watching, hope you enjoyed the video! Don't forget to check out hostinger.com/cherno and use code "cherno" to get up to 91% OFF yearly web hosting plans! ❤
@samuelrasquinha6712
@samuelrasquinha6712 4 жыл бұрын
Would love to hear more about your day job. Did you have a mentor at EA who taught you a lot of this stuff or are you completely self taught? How do you choose the technology that goes into your games for the high end products? Maybe this is for your vlog, but I think it would be interesting.
@pipeliner8969
@pipeliner8969 4 жыл бұрын
you should do this for blender!
@Blind56
@Blind56 4 жыл бұрын
Hey, thanks for the glimpse of your keyboard) looks slick Can you tell what model is that?
@ultimateskibum6813
@ultimateskibum6813 4 жыл бұрын
Yes please give us more videos Cherno!
@rodrigovieira938
@rodrigovieira938 4 жыл бұрын
Where is this code
@skyline8740
@skyline8740 3 жыл бұрын
Rest in peace source code
@casvanmarcel
@casvanmarcel 4 жыл бұрын
Next: Writing a text renderer in ONE HOUR! let's goooooooo
@kenamreemas3295
@kenamreemas3295 4 жыл бұрын
really ambitious
@madeso
@madeso 3 жыл бұрын
Should be possible: 1. Add uv support to batch renderer 2. Load font data from a bmfont/hiero, a xml file with a list of textures 3. For each character: lookup character, draw quad with the font texture and advance drawing position 4. (if time): Remember last character drawn and before drawing "advance" position based on the kerning data in the xml file
@abdel4455
@abdel4455 4 жыл бұрын
Cherno out here motivating me to get stuff done
@oblivionronin
@oblivionronin 4 жыл бұрын
great video ! Keep up the good work ! Definitely want to see some optimization and performance, love that part !
@whythosenames
@whythosenames 4 жыл бұрын
7:00 that is actually a thing and is called "pakinson's law". Impressive how you came up with this yourself :)
@Data_Corruption
@Data_Corruption 4 жыл бұрын
i made a 3d batch renderer in opengl 3.3 that draws cubes using this as a reference. Thank you for making educational content! the quality of your videos are amazing
@Chimponaut
@Chimponaut 4 жыл бұрын
Code ► Coming Soon! ...
@may007ank
@may007ank Жыл бұрын
It's still that.
@pankaka
@pankaka 4 жыл бұрын
Im beginning to see a pattern here. And i like it.
@damokl3s
@damokl3s 4 жыл бұрын
I think the check for "TextureSlotIndex > 31" should be inside the "textureIndex == 0.0f" check. Because otherwise if you have use use all the textures and want to draw another quad with an already existing texture it will start a new batch, wouldn't it?
@Wicked33
@Wicked33 4 жыл бұрын
Hey, I have a question about more dynamic batch rendering. I watched your video on dynamic geometry, and in it you essentially apply your position updates (ie position transforms) before adding the vertex positions to the buffer. If I have some more complicated transformations (rotation/scale/whatever), and the transformations are passed into the vertex shader as a transformation matrix and applied there, how do I handle batching objects that have different transformations? Are objects with different transformations supposed to have different draw calls? Or should I pre-apply all the transformations in code and just upload the transformed positions into the vertex buffer? Or is there some way to store the relevant transformation matrices in another buffer and access them by some ID in the shader?
@kplays_6000
@kplays_6000 4 жыл бұрын
you can store transformation matrices in uniforms the same way you do with textures and have an ID float in the vertex data
@NoodleFlame
@NoodleFlame Жыл бұрын
You are usually better off doing this sort of thing on the cpu. Suppose you have a scenegraph with parent child relationships, now your shader needs to know this information to be able to correctly calculate the transformation. Typically this is done by traversing the heirarchy, multiplying the transformations as you go and then storing the global transformation. If any change is made to an entities position, scale or rotation, a dirty flag can be used to indicate the global transformation will now need to be calculated again, recursively marking all children as such. You would then check this dirty flag in the get routine for the global transformation and recalculate if necessary. This stops uneccessary recalculations during lots of individiual changes in a single frame. Due to the complexity of all of this, it is acutally easier to do this CPU side, freeing up the GPU for more advanced features. With things like SIMD, matrix multiplication can be done incredibly quickly and efficiently so speed is not really of any concern
@theo-dr2dz
@theo-dr2dz 5 ай бұрын
@@kplays_6000 I came up with this idea too. However, there is a big limitation to it. Uniforms are hardcoded in the shader. The number of uniforms and the number of bytes per uniform are hardcoded. So this introduces an arbitrary cap on the number of vertices that the vertex shader can transform. Maybe there is some mechanism to transfer dynamic data like vectors to the gpu. If this exists, I'm not aware of it, I'm just learning this stuff too. Also, there is the issue that the other reaction mentions: if you have a hierarchy of transforms, transforming on the vertex shader through uniforms will quickly become unfeasible. It depends on what you want to do. If your project is for example a 2d platformer where every scene has just a limited number of moveable pieces that all move independently, doing it through the shader might be feasible. But if there is a lot of complicated movement, I think doing it on the cpu side will be a lot more manageble.
@theo-dr2dz
@theo-dr2dz 5 ай бұрын
I thought a bit more on this, and of course you could mix and match. For example, in a platformer you could transform the player character and moveable platforms on the shader. It is known at compile time how many of these there are, so that can be done through uniforms. You could hardcode that there can be 20 moveable platforms in a level. Than you have to transfer 21 transformation matrices to the shader every frame and the vertex shader can process them (I would add a transformation index to each vertex in the vertex buffer, with a magic number (0) indicating "no transformation"). The transformation of enemies and projectiles can be done on the cpu side. The number of these entities is far more dynamic, since they tend to be constantly dying and respawning. And of course, it does depend on the project what is the best approach on this.
@empireempire3545
@empireempire3545 2 жыл бұрын
Will you share the code? : )
@seditt5146
@seditt5146 4 жыл бұрын
Is there any reason to manage your buffer dynamically like this instead of just allowing the stl or whatever variation of the standard library to do it for you? The Optimizations for std::vector seem to work rather well and is much easier to use then going at it with your own iterator here. Idk, does it really effect performance that much or is vector or an equivalent as good here?
@tymbarkowychlopak
@tymbarkowychlopak 4 жыл бұрын
Parkinson's law - "work expands so as to fill the time available for its completion"
@supersquare
@supersquare 4 жыл бұрын
It's insane how accurate it is
@jordantekelenburg
@jordantekelenburg 3 жыл бұрын
Where is the code ?
@Youngermaster
@Youngermaster 4 жыл бұрын
Amazing series! Just keep this content. :D
@Hector-bj3ls
@Hector-bj3ls 27 күн бұрын
To be honest. It would probably be worse to use a HashSet or similar for checking if the texture is already used. On paper O(1) is better than O(n), but that's only because we drop constants when calculating the time complexity of functions. If you include all the extra work of computing a hash and such then it ends up being slower than a linear search. I would imagine that if you bounded the loop with the constant MaxTextures then the compiler might do unrolling or something and make it even faster. To be honest though, you're better off profiling before doing anything like that.
@Amitkumar-dv1kk
@Amitkumar-dv1kk 3 жыл бұрын
Do you plan in advance, like you already know what you need to do, have all plans ready, and then you write the code in one hour?
@sebastianzander87
@sebastianzander87 4 жыл бұрын
What exactly does the Flush function do? More than just the draw call?
@Mnmn-xi6cj
@Mnmn-xi6cj Жыл бұрын
I managed to piece it together by stopping at different times where Cherno scrolls: Flush() { for (uint32_t i = 0; i < s_Data.TextureSlotIndex; i++) { glBindTextureUnit(i, s_Data.TextureSlots[i]); } glBindVertexArray(s_Data.QuadVA); glDrawElements(GL_TRIANGLES, s_Data.IndexCount, GL_UNSIGNED_INT, nullptr); s_Data.RenderStats.DrawCount++; s_Data.IndexCount = 0; s_Data.TextureSlotIndex = 1; }
@davidandrewthomas
@davidandrewthomas 4 жыл бұрын
Is there a benefit to using a class as a namespace like that rather than just a namespace with functions? Is it just a style thing? Template parameters of the class could make a difference I guess, or maybe it's easier to change to a class with instances or something later? Just curious.
@bobdagamer640
@bobdagamer640 Жыл бұрын
You can create multiple instances of a class, but with a namespace, there is only one copy of the variables
@tomkohler1609
@tomkohler1609 2 жыл бұрын
So, you upload the vertex data on every frame to the GPU? Isn't that considered slow?
@royzhong8082
@royzhong8082 3 жыл бұрын
Is the code of this episode available now?
@iseedumbpeople6369
@iseedumbpeople6369 2 жыл бұрын
Could you please post the code that SHOULD have accompanied this video, you are mentioning it at 08:24 ?
@Red-di7zb
@Red-di7zb 4 жыл бұрын
Thanks. So I made a batch renderer and got x2 performance boost, I expected more, probably I am just a shit =), So In rendering 5 string for 35 chars in average in each, in simple rendering char by char I got 107 but now with batch I got 230, probably I did something wrong in string parsing. Also 'cause I wanna updating text it recreates (parse string and find chars in initialized char's pool) every frame, it takes a while I think and it needes to be optimized
@Red-di7zb
@Red-di7zb 4 жыл бұрын
Okay. I make a delay(0.5 second) between rendering font and now I got with a batch renderer 800 in full hd and 99% gpu load (GTX 1050, i 7700 16 GB,). Thanks for vids it is really cool and helpfull, Also I am watcing now your videos about sparky engine =)
@yayaskurt1541
@yayaskurt1541 3 жыл бұрын
two noob questions: so a batch renderer is only used to render all together? can one find out where the indices are going to be in runtime and render separately? (like 2 quads that moves)
@victorsarkisov4480
@victorsarkisov4480 Жыл бұрын
Look at the previous videos he did on Batch rendering.
@JaymzBond
@JaymzBond 4 жыл бұрын
Cherno love your videos. The code is still missing though.
@sumloser8650
@sumloser8650 4 жыл бұрын
can we get an update on hazel... on the dev branch..
@jasonbrown5752
@jasonbrown5752 3 жыл бұрын
Where is the code link?
@kamiltrzcinski
@kamiltrzcinski Жыл бұрын
been 3 years, hope the code is still "Coming Soon!"
@williankoessler5935
@williankoessler5935 4 жыл бұрын
you forgot to talk about Renderer2D::End() and Renderer2D::Flush()
@ps3man8581
@ps3man8581 4 жыл бұрын
Thumbs up just for smooth plug XD
@55mmmm
@55mmmm Жыл бұрын
21:29 I'm a little curious. "GPUs like floats" - could someone tell me how/why?
@theo-dr2dz
@theo-dr2dz 5 ай бұрын
The GPU hardware is optimised for float math.
@DrStoCazzo
@DrStoCazzo 4 жыл бұрын
does 3d batch rendering work the same way?
@anonymoussloth6687
@anonymoussloth6687 2 жыл бұрын
I followed this video and wrote the code but for some reason, it is showing a blank screen with an imgui panel
@theotherquou
@theotherquou 4 жыл бұрын
I just noticed that the Hostinger logo looks suspiciously like the Hazel logo...
@mb2282
@mb2282 Жыл бұрын
Any chance you're still able to provide the code for this?
@aliang8373
@aliang8373 4 жыл бұрын
i have an issue in EndBatch(), seems that GLsizeiptr size is not correct. Anyone has this problem. and It's been a week, please update the code
@asmaloney
@asmaloney 4 жыл бұрын
Make sure you are passing the number of bytes, not the count. I used a std::vector for the vertex buffer instead of a "naked array" like he did, so mine looks like this: struct _Vertex { ... }; constexpr uint32_t cVertexSize = sizeof( _Vertex ); ... std::vector quadBuffer; ... void endBatch() { ... const int cNumVertexBytes = sRenderData.quadBuffer.size() * cVertexSize; glBufferSubData( GL_ARRAY_BUFFER, 0, cNumVertexBytes, sRenderData.quadBuffer.data() ); ... }
@zekekossoff5447
@zekekossoff5447 4 жыл бұрын
Hey, are you gonna put the link for the code soon? Thanks for the great video and all your amazing code! P.S, you're hands down the most beautiful / handsome programmer in the world! Just had to say that
@variablejack3275
@variablejack3275 3 жыл бұрын
It's now July and we don't have a link for code
@firecode3495
@firecode3495 4 жыл бұрын
is me a LatingAmerca guy who confuse speak Australian people whit British people speak ,they sound the same. Forgeret is me , Good video man.
@talvisota1939
@talvisota1939 5 ай бұрын
Creating class, with static methods, claiming it's not singleton, but in reality state is just hidden inside cpp file..., well, it's still singleton, and thus would have been much more clear to have Renderer with instance methods and instance of renderer.
@jlfoot9094
@jlfoot9094 4 жыл бұрын
Are you from Adelaide mate?
@gifi47
@gifi47 3 жыл бұрын
There is no code in description. Press F to another coronavirus victim
@shavais33
@shavais33 3 жыл бұрын
Ah, don't ever stop gesturing. We're all nerds and goof balls, here. And we're glad and proud to count you among us, so. Wear your gesturing with pride. Here's to good times, despite it all.
@magikz1454
@magikz1454 Жыл бұрын
Where do you bind the textures?
@rasmadrak
@rasmadrak Жыл бұрын
He does this during the flush function for dynamic textures, visible at around 19:50. The static one is bound at init.
@magikz1454
@magikz1454 Жыл бұрын
@@rasmadrak thank you!
@sc5shout
@sc5shout 4 жыл бұрын
What about render queue? Do not we need it for 2D? What about transparent object and different geometry than quad? And Z ordering? I know you want to keep it simple for know. I am interested if it will be covered later or we do not need these futures, though.
@sc5shout
@sc5shout 4 жыл бұрын
Simon Farre it is not hard to draw not only quads, so simplicity is not the case actually, I am not sure it is unnecessary, for gui lets say, or even some things like spell casting, maybe, when we need to press key asap and we have got a circilar bar that will show us when skill is ready to cast (bezier curve may be helpful). I love that kind of look in games.
@theo-dr2dz
@theo-dr2dz 5 ай бұрын
Transparent object is not difficult: it's the alpha channel of the colour. different geometry: you will have to take this into account when calculating the batched vertex- and index buffers. For example, add all drawables one by one to the vertex- and index buffers. Also you can often fake this with textured quads. You can draw a circle by drawing a quad with a circular texture. z-ordering: the way he does it at this point, you will have to batch it per z level and then draw the batches in the order of z-level. But I assume that opengl is bound to be able to do that by itself. It's a 3d api after all, so there must be some way to give objects a z coordinate and have opengl draw objects with higher z on top of objects with lower z.
@InteractiveDNA
@InteractiveDNA 4 жыл бұрын
You give a lot great tips in C++. Here is a tip for you so you can help even more people. How about creating a Playlist on a complete App/Software built? From starts to finish with modern UI, Animated/UI, etc. But in a very simple approach so young kids can learn from it. Like. Stage 1: What the main propose of the Software. With blue print how the software will run before a single code is written. Stage 2. Codes Stage 3. Testing and compiling after every line of code and visuals works 100% Stage4. Completed and ready to upload/share, etc. What platforms should use,etc. I think you know what I mean. A complete software build from start to finished without adding anything to it. Very specific. With a simple software built showing everything works you will bring more people into coding. The problem with 99% of tutorials and teachers at schools is that they overload with information and that makes difficult for many out there keep learning. A lot people learn by seeing what functions, classes, variable do in a real world environment of software development. I think many people will benefit from your knowledge showing a complete simple application built using free software. Best, Ney
@adonigarcia1651
@adonigarcia1651 4 жыл бұрын
Good video like always.. can you recommend a book to learn videogames programming
@wilykary
@wilykary 2 жыл бұрын
Code?
@chakibchemso
@chakibchemso 10 ай бұрын
What about instancing 😮
@SauvikRoy
@SauvikRoy 4 жыл бұрын
Dude, please make some videos on testing and coverage.
@boximcboxface8133
@boximcboxface8133 4 жыл бұрын
Write a web browser in an hour.
@rdoetjes
@rdoetjes 3 жыл бұрын
7 minutes in and he FINALLY starts! Pffffff
@hitoshilxrd4518
@hitoshilxrd4518 3 жыл бұрын
When my index count is over max indices my batch renderer is bugging
@chrisochuko
@chrisochuko 4 жыл бұрын
You were going to not do that for a year? 😂
@dieSpinnt
@dieSpinnt 4 жыл бұрын
For y'all motivation: Procrastination is a thing
@cjgamesstudios3289
@cjgamesstudios3289 2 жыл бұрын
I thought you would code it in batch lol
@Nani-bk5op
@Nani-bk5op 4 жыл бұрын
Uhh what's a batch renderer
@h_ahmd2409
@h_ahmd2409 4 жыл бұрын
Do video on file handling please
@boximcboxface8133
@boximcboxface8133 4 жыл бұрын
What sort of file? [insert lenny face]
@flexw
@flexw 2 жыл бұрын
s_Data.QuadBuffer should be simply a std::vector
@janlucsaneaux1915
@janlucsaneaux1915 4 жыл бұрын
Plug too smooth. Had to subscribe.
@theo-dr2dz
@theo-dr2dz 5 ай бұрын
He makes the renderer a static class that has seperate create() and destroy() functions. Of course this will work if nothing special happens, but this approach is very vulnerable to exceptions. If somwhere in between an exception occurs, it all explodes in his face. He will leak a renderer on a double create or his program will crash on a double delete. I would make it a regular class with a factory function that gives a unique_ptr with a custom deleter. This way exceptions are your friends, not your enemies. I wouldn't go out of my way to make it an ironclad singleton, maybe just a static flag already_created that makes the factory function assert when true. _but what if multiple threads try to create a renderer at the same time?_ Just don't do that kind of stuff. It's a Bad Idea. It makes no sense. Just say no to multiple renderers. _but singleton is an antipattern. It's bad design_ I know this one. But in game development (and software development in general). classes of which more than one instance makes no sense are not uncommon. It makes no sense to have more than one renderer, logger, entity manager, database connection, set of story flags etc. You can make all these things static classes with static storage that has to be manually deleted, but I think it's much easier and clearer to make these things regular classes and simply create only one of them.
@SystemicNuance
@SystemicNuance 4 жыл бұрын
You remind me of Mitch625
@liamandersson5462
@liamandersson5462 2 жыл бұрын
Love ya, and I am not even gay!
@iseedumbpeople6369
@iseedumbpeople6369 2 жыл бұрын
Sure you are.
@liamandersson5462
@liamandersson5462 2 жыл бұрын
@@iseedumbpeople6369 lol
@samholland209
@samholland209 6 ай бұрын
This is 30 minutes, not 1 hour.
@asoftraiden
@asoftraiden 4 жыл бұрын
These kind of content creators are unfairly treated by youtube, the target audience is small to begin with, not like cheap entertainment creators where the target audience is large.
@suleyth
@suleyth 4 жыл бұрын
He starts actually writing at 9:35
@user-jn9pg3lx7g
@user-jn9pg3lx7g 4 жыл бұрын
challenge: custom memory allocator in 1 hour (at least pool + stack) challenge: ECS in 1 hour (lol sorry for posting about ECS under every video, but i really want to see your approach to it :))
@eemelilehtonen8628
@eemelilehtonen8628 4 жыл бұрын
No views but 2 likes.. HMMMMM
@backtotheloby1195
@backtotheloby1195 4 жыл бұрын
🤔🤔🤣
@beProsto
@beProsto 4 жыл бұрын
40 views an only 12 likes. Thats weird.
@Phroggster
@Phroggster 4 жыл бұрын
A "view" isn't counted until something like 10% of the video is watched (the exact duration is a closely guarded trade secret), and even then it takes additional time for KZbin to propigate the metric to differing content servers so they can "verify" the view wasn't from a bot. Meanwhile, you can thumb up a video immediately, and it propigates to other content servers nearly immediately.
@Alperic27
@Alperic27 2 жыл бұрын
… hmm … lol ‘code coming soon’ …. i guess 2 years is not soon enough…
Window Abstraction and GLFW | Game Engine series
29:20
The Cherno
Рет қаралды 126 М.
INSTANCED RENDERING in my Game Engine
24:57
The Cherno
Рет қаралды 72 М.
I Built a Shelter House For myself and Сat🐱📦🏠
00:35
TooTool
Рет қаралды 22 МЛН
La final estuvo difícil
00:34
Juan De Dios Pantoja
Рет қаралды 29 МЛН
Dynamic #gadgets for math genius! #maths
00:29
FLIP FLOP Hacks
Рет қаралды 19 МЛН
SINGLETONS in C++
19:16
The Cherno
Рет қаралды 193 М.
How to make C++ run FASTER (with std::async)
23:10
The Cherno
Рет қаралды 254 М.
The Blazor Competitor is Here!
15:08
Nick Chapsas
Рет қаралды 9 М.
FASTEST Way To Learn Coding and ACTUALLY Get A Job
10:44
Brian Cache
Рет қаралды 910 М.
Harder Than It Seems? 5 Minute Timer in C++
20:10
The Cherno
Рет қаралды 105 М.
Introduction to shaders: Learn the basics!
34:50
Barney Codes
Рет қаралды 277 М.
WHY did this C++ code FAIL?
38:10
The Cherno
Рет қаралды 121 М.
Batch Rendering Textures (+ Debugging!) // Game Engine series
46:30
I Built a Shelter House For myself and Сat🐱📦🏠
00:35
TooTool
Рет қаралды 22 МЛН