The first encounter with WebGL can be intimidating. The API has nothing of the friendly object-oriented libraries you might have used. It features a long list of functions used to set different states and pass data to the GPU. All of this is described in the official specification. This document is not intended for beginners, thought it will be very useful once you start to find your way around the API.
While WebGL has in fact a lot of features that will help you develop 3D applications, in itself it is not 3D. In this tutorial we'll focus on understanding how WebGL works by drawing a simple 2D shape. But first things first.
The other element we will need is the canvas. All WebGL is drawn on a canvas element. Finally we define a function called init that will be invoked as soon as the document loads. Let's start adding some code inside this function. You can name it anything you want, but "gl" seems like a good convention. Note that the 3D context is called "experimental-webgl". This is a temporary solution until the browser manufacturers decide that it's stable. By then the name will change to just "webgl".
Once we have the context, it's time to define the viewport and set some default colour to it. The viewport defines the area you want to draw the WebGL content on: in our case it will be the whole canvas.The top polygon demonstrates use of texture, and the bottom image is drawn with glDrawPixels.
Note that the textures are defined as 3 component, so the alpha value is not used in applying the DECAL environment. Source code: abgr. Snapshots: scene shown. Example of using GLUT bitmap fonts. Source code: bitfont. Snapshots: text shown. Renders two spinning icosahedrons red and green. The blending factors for the two icosahedrons vary sinusoidally and slightly out of phase. Source code: blender. Snapshots: blend shown. A simple red cube drawn with minimal OpenGL calls.
Source code: cube. Snapshots: cube shown. Example for PC game developers to show how to combine texturing, reflections, and projected shadows all in real-time with OpenGL. Robust reflections use stenciling. Robust projected shadows use both stenciling and polygon offset.
Source code: dinoshade. Arcball like rotation of a chunky dinosaur. Source code: dinospin. Snapshots: spinning shown.
OpenGL evaluators simple example with lots of options. Source code: evaltest. Snapshots: rotated 3D shown. Demonstration program exhibiting fog techniques. Source code: fogtst. Snapshots: dense fog shown. Bitmap and stroke fonts demonstration program. Source code: fontdemo.We're now going to add some things to the setup and display functions so we can draw a rectangle.
Calling glClearColor with these arguments will change the background color to white. For now, we're going to leave this line as is without explanation.
Get started with WebGL: draw a square
We'll return to what the 1. To allow us to draw, GLUT needs to clear the screen every time we work. This is accomplished through two functions, one at the beginning and one at the end of our display function:. By using glClearwe give ourselves a clean slate to work on; everything that was in our buffer the place in memory where we store the rendering image before is gone.
We're now using a new buffer, so at the end of the function, we need to switch that buffer into our window. Don't worry if you don't fully understand why these two functions exist just yet. You'll have time to learn. Again, ignore the arguments to glColor3f.
Just trust us for now that this will make our rectangle black, so we can see it against the white background. Then we actually draw the rectangle using the function glRectf. We pass in as parameters to glRectf two sets of numbers: the x and y coordinates for one vertex of the rectangle you want to draw, and the x and y coordinates for the opposite vertex. An important thing to note is that these x and y coordinates are not given in pixels, but rather in viewport coordinates.
You'll notice, if you compile and run the program using the display function above and then resize the window, that your rectangle will grow and shrink as your window does. This is because we haven't set our viewport. The viewport defines how coordinates are mapped from OpenGL space, which uses floating point numbers, to the window space which obviously uses pixels. By default, the viewport assumes that the top left is -1, 1the bottom left is -1, -1the top right is 1, 1 and the bottom right is 1, -1regardless of the window position.
It is time to actually draw something using OpenGL. First, let me mention that OpenGL is a low level API, this means that it has no support for drawing complex geometrical objects. The basic geometrical primitives that the core OpenGL profile provide to us are points, lines and triangles. For simplicity, we are going to use only two dimensional drawings in this article, but keep in mind that OpenGL allows us to represent three dimensional objects, more on this in a future article.
From a geometrical point of view, a triangle is completely defined by the position in space of his three corners or vertices. In OpenGL terminology, a vertex can be seen as a collection of attributes like position, color, texture coordinates etc …. In the above figure we have four triangles and twelve vertices. If you look closely, you may notice that the points are written counterclockwise, this is important to keep in mind.
By default, in OpenGL, a triangle with his vertices stored in counterclockwise order is said to be front facing. Why is this distinction important? We can instruct OpenGL to render only one of the two faces of a triangle surface the front or the back ; the default is to render both faces. Another observation about the above array is that it stores only the xy coordinates for our triangles, this is because the z coordinate is zero for all twelve vertices.
So, how does OpenGL draws our triangles, now that we have their vertices in an array? The first step is to transfer the content of the above array in a Vertex Buffer Object.
A VBO needs to be created, allocated and filled with data. We can also fill the VBO with data in the allocation step:. Line 3 from the above piece of code will create a handle for our VBOusing the glGenBuffers function. Keep in mind that this function can create an array of handles if needed; for our particular case we have a single VBO so one handle will suffice. Once a VBO is created, we need to bind it in order to modify or use it, this is what line 6 does with the glBindBuffer function. Once we have our data in a VBOwe can send it through the OpenGL pipeline - a number of steps and transformations through which our vertices will pass; the result is written in a framebuffer.
The glfwSwapBuffers function from GLFW will replace the current, visible framebuffer the surface of our windowwith the result of the rendering process.
A simplified scheme of the OpenGL pipeline is presented in the next figure:. From the point of view of a beginner, what is important in the above scheme are the vertex shader and the fragment shader.OpenGL provides us with several different types of shapes that we can draw in order to get the geometry we want on the screen.
In brief, they are:. A line strip is a series of lines, where each point in the line has a point before it and after it, except for the end points. This is useful if you want to draw a series of lines, maybe you want to draw a circle and a circle is a set of lines.
So the first point will automatically connect to the end point via one line. A quad is similar to a polygon, but it limits the number of vertices to 4. This allows OpenGL to break it up into two triangles quite simply for faster processing. In short, a quad is a shape with 4 sides. A quad strip is a line of quads, where each quad shares two vertices with the quad before, and after it. Triangles are the ultimate shape in 3D geometry, this is because you can quickly and efficiently calculate how to fill them.
A triangle fan has one central vertex, and all other vertices form triangles extending from this point. Very useful for drawing filled circles. A triangle strip is similar to a quad strip and a line strip, but it uses triangles, where two of the three vertices are shared with a triangle before and after itself.
I am going to implement a new method, in order to keep our code nice and tidy. This method will be called renderPrimitive and will take no parameters. Now inside of our display method, we are going to want to call this, so before our glFlush line, make a call to render Primitive.
Ok, good, we have a method we can fill to draw our shape, and we are calling it in our render loop. The default position for the camera in OpenGL is at the world origin, which is 0, 0, 0 in 3D space. Because we have a near plane at 1. In order to make sure we can see our shape, instead of positioning further along the z-axis when I set the vertices, I am going to move the entire scene back 5 units, so anything we draw at 0, 0, 0 will actually be drawn at 0, 0, 5.
This may sound a little complicated, but trust me on this, and it will be explained a little more in the camera tutorial as the camera tutorial consists of 4 calls we do, before any of our rendering, to make sure we can see what we want. Now, you can go ahead and add a line before our call to renderPrimitive which will translate move our scene 5 units in front of us. This is done with a call to glTranslate which takes three parameters, each one relating to how much we want to move everything on the x, y and z axis.
And finally everything is now set up for us to actually draw our square. When we want to tell OpenGL we are drawing some geometry, we need to make two calls, one at the start to tell OpenGL we now want to draw a shape, and one at the end, telling OpenGL we have finished drawing our shape. These calls are glBegin and glEnd, relating to the beginning and the ending of our shape drawing, and glBegin takes one of the geometry types I mentioned earlier as a parameter.
My understanding is that I need to define an array of vertices like. Edit 2: We are using OpenGL 2. Edit: Why does this now draw 4 vertices? I know this function is supposed to work because it is from an example. It prints points but when I change it it won't draw the 4 vertices I define. Edit: I was actually painting something the entire time but it was too small to see. Once I changed the point size with glpointsize I was able to see it.
There are plenty of ways to do this, I mention here the 2 most popular one, so vertex array objects and immediate mode. Note: For some languages like java if you write a floating point number, you get a double instead of a float, so you need to give a suffix to it, like 0. This is the easiest method for drawing simple things, however, because you do a lot of native API calls, it is really slow compared to other techniques. Instead, if possible, and you GPU allows it, use Vertex array objects.
This can make your game even faster, if you have multiple of the same model, like a 2d plane for sprites, different tree models, etc. In these cases, you only need to bind the vertexArray once, then render different objects at different location, with different attributes, it depends on you what you do with it.
Sadly, this topic is too in-depth for this post, and because I don't even know what language you're using, I can't even link a tutorial. Google it. And after that you have to update your screen, the way to do that depends on which library you are using for windowing.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Your code will not even draw a circle.
If anything, it will draw a diagonal line extending out of the view area very quickly. A circle plot would need to use sine and cosine, based on the radius and angle.
Sample code is below. Since in the case you have to draw square from the mid point which is interaction of two diagonals of square. You use the following facts and draw the same. If your point is at 0. So you can easily determine the point coordinate of four corners as in the figure given below and code it accordingly.
Learn more. Asked 3 years, 9 months ago. Active 3 years, 1 month ago. Viewed 9k times. Coder Coder 5 5 silver badges 23 23 bronze badges.
A square or a circle? Active Oldest Votes. I have not tried this code, but it needs to be more like this to draw a square. Weather Vane Weather Vane MD XF 6, 6 6 gold badges 27 27 silver badges 58 58 bronze badges.
Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Podcast Programming tutorials can be a real drag. Featured on Meta. Community and Moderator guidelines for escalating issues via new response….
Feedback on Q2 Community Roadmap. Triage needs to be fixed urgently, and users need to be notified upon…. Technical site integration observational experiment live on Stack Overflow. Dark Mode Beta - help us root out low-contrast and un-converted bits. Related