I'm trying to run the code to study it, but I'm getting several errors. Can you help me or upload a Makefile to the repository?
@user-jz2sb5xe2y
17 күн бұрын
Nice Program, would be amazing If you Implement fill flood algorithm as well.
@multiarray2320
18 күн бұрын
was expecting an error message at the end xD
@IamWassim
18 күн бұрын
Thanks for the idea tho haha
@Byynx
21 күн бұрын
What font is that ? It's not the Visual Studio default one right?
@IamWassim
18 күн бұрын
No, i'm using a different font. It is JetBrains Mono.
@valsk01
13 күн бұрын
@@IamWassim JETBRAINS ARE THE BEST!!! :D
@Pepcen
22 күн бұрын
When fixing bug #1 you could have just used a rectangle. It'd be so much easier and efficient.
@papeador-x
28 күн бұрын
Whats the font that you use in visual studio?
@pixelreset1572
Ай бұрын
Such a good training project, I read some comments before posting this one, and yeah, I think it would be better to do the drawing stuff within a material shader. I would recommend rendering the dots based on UV, determining if the mouse has been released in between frames and if not, you can draw 2 triangles (aka a rectangle) between the new and old circle, which is an insanely easy implementation :)
@midnightfuture
Ай бұрын
Cool project, well done. I'm sure you learned a ton in the process!
@Byynx
Ай бұрын
When you freely draw are you creating a new vertex object for each point you make or do you have a single VBO with the size of the APP and you just work pixel by pixel in the fragment shader?
@Mohammed_designer9
Ай бұрын
Why you write std::cout ?? You can write just cout, using namespace std;
@airman122469
Ай бұрын
“From scratch… with OpenGL” Ummmmmm… if you’re not going directly to the frame buffer it’s not “from scratch,” not really anyway.
@girlazo2222
Ай бұрын
I'm glad youtube recommends channels like yours!
@MED_Laaguidi
Ай бұрын
are you moroccan bro?
@pedrodeazeredonogueira9661
Ай бұрын
>from scrach >open GL
@Cadknowledge
Ай бұрын
can you make something like manim with good UI in c++ ?
@isaac45896
Ай бұрын
Nice video. the fps in your app goes down fast maybe because of using a lot of draw calls, you should look for some videos about batch rendering, secondly, to gain in performance : use squares vertex instead of circles vertex then just apply a circle shader or texture to simulate the circle stroke. that's all what i can say
@Fernando-du5uj
Ай бұрын
whats your msvc colorscheme?
@HelloWorld-pw4fg
Ай бұрын
Lol, I am making a 3D engine and use GLFW too. What a luck.
@Kave-qp1yt
Ай бұрын
how can i install the program?
@Vorono4ka
Ай бұрын
Really funny, I like this video
@isaacgraphics1416
Ай бұрын
This is a cool video, I'm grateful you talked a bit about some of the basic starting steps, that's pretty uncommon in these kinds of videos
@MartinWoad
Ай бұрын
The problem is that by importing windows.h you've basically tied your program to Windows forever, until you go back to the lines of code you've written that are utilizing it and rewrite them or someone uses Wine. I would have personally abstracted that layer and instead and made a class for each platform that would then handle the logic for each OS. Or otherwise.
@TheRealZitroX
27 күн бұрын
Don’t have to when just trying out. I see much more problems with the shaders and circle draws each frame. Abstraction is for bigger problems or when you know you want to work on different operating systems
@DLCSpider
Ай бұрын
I did something similar about a year ago but mostly in software. It was not C++ but C# with Monogame, so with all the added "benefits" of a garbage collector, slightly worse optimizing compiler and worse Windows interop. Managed to get the brush size to a radius of around 400px before it became noticably laggy. I think the steps between brush samples were smaller (sqrt(radius? diameter?) looked good to me) and it was all done with floating point because 8bit per color channel is not enough if you want to make the standard blending procedures look good (brush had a smoothstep gradient from the center). It took some serious SIMD optimizations to get to that radius. All calculations were done on a single core but a second thread improved my performance only by 57% and more cores were worse, sometimes even worse than the single core solution. I guess I maxed out my RAM bandwidth and just starved the system with more cores. Since I only used 128bit vectors (RGBA * 32bit float) and 256bit/512bit vectors do exist but would've required major refactoring, I threw MT out and called it done for now. I think I also added undo functionality and a color picker but never managed to make a usable UI. I was also interested in tablet support and pen pressure but the documentation was already dire for C++ and I gave up after weeks and weeks trying to get it working in C#. If you can get it to work, please make a video about it! I do understand if you don't want to, though ;) Since I spent so much time optimizing something similar, the first thing I noticed was your FPS tanking from 3000 to 100-200 :) Maybe try drawing just two triangles per circle with a texture or blend everything directly in a compute shader. Gets you different shapes for free, too! If you tile the image and give every brush sample a stroke generation counter (increment only if the user stops drawing) you can implement a decent undo that doesn't kill your RAM after 5 minutes.
@PymeCheckTV
Ай бұрын
Good stuff!
@htnguyenpanda
Ай бұрын
Awesome video!
@cvabds
Ай бұрын
I bet you can't do that on templeOS, I will only subscribe if you like this and confirm you will do that
@yyvan5125
Ай бұрын
A while back I made something similar using Raylib for Android and C, it was really fun
@abrarmasumabir3809
Ай бұрын
bro what drawing softare were you using at 3:11
@anon_y_mousse
Ай бұрын
I still remember my first drawing program. I used MFC and drew directly on a window canvas. It was garbage and I quit working on it after I got it working, but maybe I should revisit the idea since that was back when I was using Win98.
@LevitskiSRGE
Ай бұрын
Now ask yourself, what problem do you want to solve?
@S.M_Gaming.
Ай бұрын
now made nodepad!!
@yonilaskov340
Ай бұрын
how have you came to make this, figuring it out
@MahmudulHasan-ld3nz
Ай бұрын
bro what drawing softare were you using at 3:11?
@tetraizor
Ай бұрын
Goodnotes
@rexoverwatch
Ай бұрын
very cool
@grevel1376
Ай бұрын
storing each dot is a bad idea
@informagico6331
Ай бұрын
Not being constructive is too
@chapanharder
Ай бұрын
Nice bro.
@jackcomas
Ай бұрын
Better than Adobe Photoshop
@samllea1
Ай бұрын
YOU MADE MY GOOGLE GO OFF AT 12 IN THE MORNING 😭
@lolcat69
Ай бұрын
Store the colors in the vertices, and instead if drawing a circle that way only use 4 vertices, make a square and draw a circle with shader code
@lolcat69
Ай бұрын
Or, make a "canvas" buffer that lives on the CPU and draw pixels to that, then you send it to de GPU with OpenGL to render it, so you don't have to deal with shaders that much and you will have a constant size of objects for the drawing
@michaelhawthorne5516
Ай бұрын
Your vector of vectors made me sad
@RoyaltyInTraining.
Ай бұрын
I see a lot of problems here. First of all, as others have pointed out already, you should immediately render all brush strokes that occurred between two frames into a separate framebuffer, then display that framebuffer in the UI without clearing it between frames. That way it acts as an accumulator, and you can stop redrawing all previous brush strokes for every new frame. Instead of using lots of polygons to make circular shapes, I'd use a square or a very low poly circular shape, and then perform a check inside the fragment shader if the current fragment is inside the shape or not (using the formula x^2 + y^2 <= radius). If it's outside, discard the current fragment. GPUs are really inefficient at drawing small polygons, but executing the same code over a bigger continuous area is basically free. Another benefit is that the circle will be mathematically perfect without any polygon edges. Additionally, do not recreate or modify VBOs unless you absolutely have to. If you want to draw multiple circles or brush strokes, use the same set of polygons and call the draw function in a loop, while using a matrix uniform in the vertex shader to transform them to different points on the screen. For very basic applications, you could also use a uniform 2D vector as an on-screen offset and a uniform scalar as a brush scale, but a matrix will let you define an arbitrary linear transformation (translation, rotation, scale, stretch, shear), which will be convenient for the next point I'm making. You better get used to matrices and linear algebra, it's the bread and butter of computer graphics. To connect the gaps that appear with fast cursor movements, I'd just elongate the square, rotate and position it so the end points line up, and modify the fragment shader so the line with rounded endpoints is drawn correctly. I'm also thinking of a really cool method of using vertex attributes to define a sort of local coordinate system within the brush stroke, which could be used to do some really fancy things, but that explanation would be a little too long for a yt comment.
@tranquil31
Ай бұрын
beautiful
@samarthtandale9121
Ай бұрын
You truely are genius bro !!! Subscribed!
@tranquil31
Ай бұрын
awesome video, please keep making vids! subbed
@akidanis6984
Ай бұрын
Great vid! I love how the more lines you draw the fps gets lower lol. Keep up the good stuff ;0
@skilz8098
2 ай бұрын
Perhaps add in some basic features such as a clipboard with history (undo and redo) in conjunction with shapes outline tool for cutting, copying and pasting. Also, with the color settings for the brush you could implement a pre-render buffer that stores the current selected brush color that will eventually get sent from the back buffer to the front buffer through the swap chain. With that you can create a priority queue of render buffers where each brush color is stored as its own instance then through the use of the priority queue implemented in a FIFO (First-In First-Out) manner by x number of entries within the priority queue that can be processed within the desired render frame count that gets set to the pipelines update frame to be concatenated on the back before being presented to the screen or front buffer. There are many various ways to achieve this through the use of glTexImage2D, glGetTexImage, glGet, glRenderBuffers, etc. Once you have the FIFO queue populated with various color changes per brush stroke(s), for each change of the color you should make a copy of the front or present buffer as that will be the base image buffer, then a secondary new buffer will be created when a new color is selected for the brush object. This will then draw to that secondary buffer. These two images will then have to be added or concatenated together before being sent to the back buffer within the swap chain on the renderer's update call. This priority queue doesn't have to be large in size. If you're rendering at say 60 frames per second, a user can't even change the brush color that fast. So, there will be 60 frames drawn by the time they change a color and another 60 or so frames drawn before they even start to use the mouse to make the draw call. So, this priority queue like system might only have a maybe 4 - 12 images within it at any given time. You'll need to take the present front buffer and copy that into the primary buffer within this queue, and then any subsequent changes to the brush color can be saved as its own 2D image and added or blended with the previously drawn screen buffer. Now as for how you add or blend these two images to create a new image that will be sent to the back buffer within the swap chain depends on the functionality you would want. For example, if there is already a color image on the buffer at that pixel location that is not equal to the canvas or the render contexts background color then you could either A: add the existing color with the new color to get a blend of the two colors, B: take the abs of the result of subtract the existing color with the new color, C: preserve the original and discard the new, D: overwrite the existing with the new, D: compare the two colors and choose one based on some criteria, etc. Heck you could implement all of the above as different modes of drawing and color blending within the canvas. And these calculations that need to be done pre-processing before sending it to the swap chain can be done within a compute shader that it's result through the update call gets passed to the pixel shader instead of trying to get the pixel shader to do these calculations. By treating these 2D images or buffers as textures there's a lot you can do with them. By creating these as a texture object with a unique texture id, it's quite trivial to use them in your shaders and reference them through uniform values. You only need one instance of each image, and with that you can reference it several times. With this you can easily extend your application's functionality to include a variety of tools such as implementing a clipboard, copy and paste, an undo and redo system even with a recorded history of events that I had previously mentioned at the beginning of these suggestions. You can even add in a scissors element that allows you to select a region within the drawn canvas and to either cut it from the canvas or by copying to the clip board to where you can then select it, then either resize it, reshape it, or even move it across the canvas, also previously mentioned. If you really want to challenge yourself, you could even implement a text rendering function within it... Now that's a challenge! I've built 3D Graphics/Rendering/Physics/Game Engines from scratch; I've done some Hardware Emulation. Some basic parsers for a simple scripting language, a little bit of 3D Audio processing, very little networking, some A.I. - Machine learning algorithms (Python), the rest mostly C/C++ and very little C#. And throughout all of, one of the toughest things to program and get correct is Font Rendering especially when you are rendering your own custom fonts. Within the context of font-text rendering; the size in pixels is one thing, the font color as well as foreground, background and border color is kind of trivial even if transparency is involved. The font types are another thing as there are two variants, monospace and proportional. Monospace is kind of trivial but proportional is a lot more involved. You have the character widths, the padding or spacing, the width and the height, there's also offset values, but one of the trickiest things is handling a set of specific characters within all possible printable characters. This is due to the fact that a given line of text regardless of font, font type, size or color has a baseline and some of them have dangling characters and that has to be accounted for within the calculations. Also, the size of the line of text has to accommodate for that as well as the tallest character with several pixels of padding between each line (line spacing). Then you have the size of the text buffer to consider. Also, if you have a text box with several lines, how do you go about wrapping to the next line? Do you stretch all of the characters so that all of the lines appear like a box with even edges on both vertical sides? Do you wrap to the next line with a new line character such as them pressing the enter key or do you do it automatically when the textbuffer's current size begins to exceed the max width? If so, do you just move that current word to the next line or do you break it at a syllable and append a hyphen in the middle of the word where there is no space or newline between them yet everything after the appended hyphen is to be rendered on the new line. Yes, Font - Text Rendering is one of the trickiest, most challenging things to get correct. And these are simple 2D Texture-Sprit pixel fonts. I didn't even touch or get into Vector Fonts or Rasterized Fonts... Oh, and some fonts files or types can have their internal date compressed, so if you're loading and reading in a font file to parse its data for use within the application, you may or may not have to uncompress it especially if that font file is a "family of fonts" as opposed to just a single font. So yeah, it's one of the more challenging and or daunting things to get correct. Even when I was doing collision detection algorithms, every once in a while, I might have overlooked an off by one error... Within font-text rendering that was a common routine occurrence. When you're doing collision detection or rendering a model, being off by a single pixel may not be noticeable and may or may not even effect transformations, physics, collisions or animations. Yet when it comes to font rendering, one pixel off and the whole thing is wrong! Happy Coding!
Пікірлер