Bezier Flag Renderer

OpenGL Flag Renderer

In this blog I will be talking about my implementation process of an openGL flag renderer which is the first homework of Ceng469 Computer Graphics II. I have used an Dell Vostro-5481 Laptop for my benchmarks which has an Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz with 8 cores and NVIDIA MX130 GPU.


Overview
 

I have written my program in C++ using OpenGL, glfw, glew, glm and stbimage library which takes an image file as argument to use as flag texture and generates control points for multiple Bezier patches than renders those patches after sampling them.

The program allows users to increase or decrease sampling rate and number of Bezier patches to be generated by using W/S keys and E/D keys respectively.

Implementation Process

Hello Bezier

Since this was my first time dealing with Bezier patches, I started with rendering a single static Bezier patch before creating animated multiple patches. For sampling the patch I have used the formula below we have seen in the lectures which uses Bernstein polynomials.

    After a few lines of code,  which I have written using our professor's sample code, and debugging I have managed to render my first Bezier Patch.


After rendering a single patch I have added texture mapping to see how it would look. (Sadly LLVM's logo doesn't demonstrate phong shading well)

 


After drawing a simple patch animating it was very simple. I have just changed the coordinates of the middle control points continuously in each frame in the form of a sine wave. 

 

Increasing the Number of Bezier Patches

Since I have managed to render a single animated patch it wasn't very hard to render multiples of them. I have just did the same rendering operation in a loop. The most important part of this process was to fill the openGL's buffer object so that one glDraw call would draw all the patches. If I had used multiple buffer objects and multiple draw calls it would create an unnecessary performance overhead.

Of course the other important issue with rendering multiple patches in a flag was to keep the flag continuous. Which had the following requirement.



 
In order to do that I have generated all left and right edge control points of all patches in a single plane then animated the middle control points in the same amount which guaranteed that my patches would be continuous. I know that is a little bit boring and repeating animation style but I have written my code in a way that If someone wanted to change it they could just write another function in C++ for generating and animating control points and my code would still render those as a flag.  

While writing my code I always tried to keep it generic and not hard-coded so after making all these progresses changing the number of Bezier patches and sample size with key strokes dynamically was a pieces of cake. Hence I have got the following results.




 

Even though I wasn't fully satisfied with my animation style. As I mentioned before knowing that my code was open to modification was relieving so anytime I want to change it I can come back and change my flag animation style.

 

 

Bug That Have Occurred During Implementation

 The two of the mistakes I have made in my program was about normal computations  which caused my shading to look weird. 




The first one was easy to detect because I was dealing with a single patch but the other one was a little harder because I was dealing with multiple patches and I had thought that I had managed to compute normals succesfully so I thought my mistake was about generating control points. After wasting some time on trying to find a bug in control points I have realized that problem was in shading so I checked my normal computations again which turned out to be the actual problem.

One Other funny looking bug was created by a miscalculation of my vertices heights but It was easy to fix becasue it was obvious.


Other than these I didn't have any important bugs in my code.


 

Benchmarks
The following table shows how many frames per second I was able to get with the corresponding samping sizes and patch numbers on a Dell vostro 5481 which has
Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz with 8 cores and NVIDIA MX130 GPU.


  

Epilogue

This was a nice introduction to curve rendering for me.  Even though what I have implemented could be achieved much more efficiently and easier with tessalation shaders. Implementing a program like this was informative about curver rendering. As I have mentioned in the future I'm planning to change my animation style to a better, more realistic flag but for now I will stop here.


Comments