Table of contents
1.
Introduction
1.1.
What is OpenGL
2.
Cinder Textures
2.1.
Example
3.
Cinder Basic Shaders
3.1.
Vertex Shaders
3.2.
Fragment Shaders
3.3.
Implementation
3.3.1.
Explanation of Keywords
3.3.2.
Explanation of Code
4.
Cinder-Framebuffer Objects
4.1.
Setting Up Code For Cinder-Framebuffer Objects
5.
Images in Cinder
6.
Frequently Asked Questions
6.1.
What is a frame buffer in OpenGL?
6.2.
Why do we need a frame buffer?
6.3.
What language is Cinder?
6.4.
What can replace OpenGL?
6.5.
Is OpenGL for C or C++ language?
7.
Conclusion
Last Updated: Mar 27, 2024
Hard

Cinder-Framebuffer Objects

Author Vaibhav Mani
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Hello Ninjas, ready to learn a new topic? The name cinder sounds so fascinating and new to us so let's see what exactly it is. Well, Cinder is a framework that helps you create complex interactive real-time audio-visual works. Cinder is one of the most useful and professional coding frameworks that use the low-level coding language known as C++.

Introduction

What is OpenGL

OpenGL is an open source for graphics programming, and it focuses on processing the application using specialized hardware components through GPU(Graphic Processing Unit). The Khronos Group keeps the source up to date.

Relation Between OpenGL and Cinder

The Cinder OpenGL API is created to abstract as much as possible of the low-level points of OpenGL, and we can use this OpenGL API  by keywords ci::gl; let's now go through some topics in Cinder.

Cinder Textures

First of all, we need to know what texture is. A texture is a collection of one or more images. It has distinct boundaries related to those images, which define the characteristics of that specific image. These characteristics include its types, size, and image format.

Images in OpenGL usually get the form of textures, and Cinder executes the API through its specific classes only, such as for textures using gl::Texture2d.

Example

#include "cinder/gl/platform.h"
#include "cinder/gl/Texture.h"
#include "cinder/GeomIo.h"
#include "cinder/PolyLine.h"
#include "cinder/Shape2d.h"
#include "cinder/Camera.h"
#include "cinder/Font.h"

class BasicApp: public App
{
	public:

		void setup() override;

	void draw() override;

	gl::Texture2dRef pTex;

};

void BasicApp::setup()
{
	auto load_img = loadImage(loadAsset("car.jpg"));

	pTex = gl::Texture2d::create(load_img);

}

void BasicApp::draw()
{
	gl::clear();

	gl::draw(pTex);

}
You can also try this code with Online C++ Compiler
Run Code


Here, we have called the function named loadImage() along with using its asset, and then we have passed the image to it and stored the result in a variable 'img'; we have then given the variable 'img' to the function named as  gl::Texture2d::create() which accepts the imageSource which we have passed.

Let's understand some keywords' meanings.

  • loadImage (DataSourceRef dataSource, ImageSource::Options options=ImageSource::Options(), std::string extension="")  This loads an image from a particular source; if the file type is "jpeg," it will force the image to get loaded in JPEG only.
     
  • Texture2dRef create (GLenum target, GLuint texture, int width, int height, bool do not dispose of, const std::function< void(Texture2d *)> &deleter=std::function< void(Texture2d *)>()) This creates a texture based on the image source, which can also be resized. In the above example, we have simply drawn a texture; other than this, we can undoubtedly add more texture to a 2D or 3D image, which is known as texture mapping.

Cinder Basic Shaders

Ninjas, it's time to graduate with the cinder shaders concept. Of course, we have seen in many pictures that different shades are there, which pop out of the image beautifully, making it more versatile. 

The shader is a program written in GLSL (in the case of OpenGL), and it runs on GPU. In general, will use C++ code to implement shaders. We have two kinds of shaders one is a vertex shader, and the other is a fragment shader.

Vertex Shaders

As the name gives us an idea of something related to vertex, the vertex shader implements the code on the vertices of whatever geometry, shape, or image we are given or have taken.

Fragment Shaders

On the other hand, Fragment shaders implement the code on each pixel of the geometry or the shape of the image that we are given.

Implementation

#include "cinder/gl/platform.h"
#include "cinder/gl/Texture.h"
#include "cinder/GeomIo.h"
#include "cinder/PolyLine.h"
#include "cinder/Shape2d.h"
#include "cinder/Camera.h"
#include "cinder/Font.h"

class BasicApp: public App
{
	public:

		void setup() override;

	void draw() override;

	// Making variables

	CameraPersp xCam;

	gl::BatchRef xCube;

	gl::GlslProgRef xGlsl;

};

void BasicApp::setup()

{
	xCam.lookAt(vec3(3, 2, 4), vec3(0));

	xGlsl = gl::GlslProg::create(gl::GlslProg::Format()

		.vertex(CI_GLSL(150,
			uniform mat4 ciModelViewProj;

			in vec4 ciPos;

			void main(void)
			{
				gl_Pos = ciModelViewProj * ciPos;
			}

	))

		.fragment(CI_GLSL(150,
			out vec4 oColor;

			void main(void)
			{
				oColor = vec4(1, 0.5, 0.25, 1);
			}

	)));

	mCube = gl::Batch::create(geom::Cube(), xGlsl);

	gl::enableDepthWrite();

	gl::enableDepthRead();

}

void BasicApp::draw()

{
	gl::clear(Color(0.2 f, 0.2 f, 0.2 f));

	gl::setMatrices(xCam);

	mCube->draw();)
You can also try this code with Online C++ Compiler
Run Code

Explanation of Keywords

Let us look into the explanation of some keywords used in the code above.

  • GlslProgRef :: create (DataSourceRef vertexShader, DataSourceRef fragmentShader=DataSourceRef(), DataSourceRef geometryShader=DataSourceRef(), DataSourceRef tessEvalShader=DataSourceRef(), DataSourceRef tessCtrlShader=DataSourceRef() 
     
  • Format &vertex (const DataSourceRef &dataSource)  supplies GLSL source for the vertex shader.

Explanation of Code

  • We have our first line uniform mat4 ciModelViewProjection; a uniform is a variable passed into the shader in c++ language. There are many customized uniforms also. 
     
  • In the next line, we can see in the keyword that it declares a variable that stores per-vertex data supplied by geom::Cube.
     
  • The in keyword has variable ciPosition; Cinder understands that it has to supply relevant position data produced by geom::Cube.
     
  • Next, we can see the main() function. Here we see how the actual code of the shader will look, as we used to do in our standard C ++ language.
     
  • Now comes our implementation of gl_Position = ciModelViewProjection * ciPosition, here gl_Position is a built-in variable, and in this, we are setting the value of gl_Position by a vertex shader to specify the final position.
     
  • Finally, looking into our fragment shader, which has the function to set the final pixel color of the image.
     
  • We first find an out variable called oColour, which stores the result of the fragment shader.
     
  • Boom, our one-line implementation sets the variable oColour to a constant value representing the orange color.
Cinder Basic Shaders

Cinder-Framebuffer Objects

When we use cinder-Framebuffer Objects, we can get the result of our processing command before it gets displayed on the screen. You get a very idea of your result. So, we can say that cinder-Framebuffer Objects help us get an idea of our result before it gets displayed on our screens. E.g., when we want to blur our screen.

Setting Up Code For Cinder-Framebuffer Objects

Below are the steps you can follow:

  1. Specifying the size of Framebuffer Objects in pixels.
#include "cinder/gl/Fbo.h"
using namespace ci;
gl::FboRef myFbo = gl::Fbo::create( 640, 480 );


2. We have not specified any size for the screen, so it is rendered as a standard screen-based frame buffer. To make use of FBO, we use binding

myFbo->bindFramebuffer();


3. Any rendering will be done to our Cinder-Framebuffer Objects instead of our direct screen. After we have completed off-screen rendering, we need to restore the screen as the primary frame buffer object.

myFbo->unbindFramebuffer();

Images in Cinder

Cinder also enables images to be rendered on the screen. Ninjas, these are also interesting to learn. The simplest way to display an image is by following commands.

// Your App's setup() method
gl::Texture texture = loadImage( "image.jpg" );

// And in your App's draw()
gl::draw( texture );


Let's understand this code

1. loadImage() function can load various images along with different image formats. It can load images from different URLs and other sources.

2. We have objects and functions designed for distinct processes such as loading, manipulating, and transferring data. E.g., loadImage().

3. We will be blown out if we explore Cinder's image capabilities more. They are soo amazing. 

Frequently Asked Questions

What is a frame buffer in OpenGL?

Cinder-Framebuffer Objects help us to get a blurred idea of our result before it gets displayed on our screens. E.g., when we want to blur our screen.

Why do we need a frame buffer?

We need a frame buffer to get a flexible idea of output before it gets rendered on the actual screens. It is primarily implemented in large films to see pre-processing effects.

What language is Cinder?

Cinder is a framework that helps you create complex interactive real-time audio-visual works. Cinder is one of the most valuable and professional coding frameworks that use the low-level coding language known as C++.

What can replace OpenGL?

A more modified version of OpenGl can replace it in the future since technology upgrades daily. 

Is OpenGL for C or C++ language?

As we have studied above, OpenGL is an API; it needs language to operate, so people have chosen c++ as that language. 

Conclusion

So, we understood that Cinder is a great framework that helps us create real-time 3D and 2D audio-visual illustrations. Cinder is one of the most useful and professional coding frameworks that use C++. Cinder provides an interface for all types of multimedia, like audio, video, graphics, images, etc.

Cinder has the availability to play with screen savers, provides 3D classes and 2D classes, records audio, and plays video. Overall, we can say that Cinder is totally bringing a revolution in coding.

Refer to more amazing content to enhance your knowledge.


You can refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingSystem Design, and many more!

Head to our practice platform, Coding Ninjas Studio, to practice top problems, attempt mock tests, read interview experiences and interview bundles, follow guided paths for placement preparations, and much more!

Happy coding, Ninjas!

Live masterclass