Thursday 28 June 2012

[Tut] OpenGL Basics [Tut]

Basic OpenGL Features


The whole purpose of this tutorial: discere docendo (damn school latin :D)

Vertices


Definition of Vertex :
In geometry, a vertex (plural vertices) is a special kind of point that describes the corners or intersections of geometric shapes (from Wikipedia)

In my own words that would be:
every shape is defined by a given number of vertices, being the "edges", which our polygon is defined by.
Vertices in OpenGl can also have their own color, transparency and they even can be textured. Vetices can have up to 3 dimensions.

Polygons and more:


The word "polygon" derives from the Greek polús "much", "many" and gonía "corner" or "angle"
A polygon is a two dimensional shape, which is the prototype of a polyhedron. A polyhedron is a body in 3 dimensional space with flat sides.
Polygons as well as polyhedron are subtypes of the more general polytope, that is described as a geometric object with flat sides, which exists in any number of dimensions.
A polygon is called a 2-polytope and a polyhedron is called a 3-polytope. More general a geometric object in n dimensions is called n-poytope.

you might ask, if a sphere is a polyhedron, too and the answer is yes. In theory, a sphere is nothing else then a geometrical body with an infinte amount of sides all
with the distance r to the middle point.

just for those interested: a Vertex is a polytope in 0 dimension. A polygon in 1 dimension is called an edge.

Primitives


you always draw counter clockwise, that means you have to define your vertices like this. It does not matter, where you start though.

Points
Points are 1-dimensional geometric shapes. They are just the Plural of the Point, that is never used, since it is useless.
You can draw 1 to n points with this function, where n is an element of the natural numbers.

Code Example:
Code:
    public void points()
    {
        GL11.glPointSize(5F); //this is the size of the points you are going to draw
        GL11.glBegin(GL11.GL_POINTS);
        {
            /**
             * this may be one of the uses for GL_POINTS, you could also draw an Array of Points
             * with this very easy by looping through it.
             */
            for (int i = 0; i < 20; i = i+2)
                GL11.glVertex3d(0D, i, 0D);
        }
        GL11.glEnd();
    }

Lines
A line is a shape, that connects 2 vertices directly.
It has a direction, a magnitude and start and ending points. All of these properties can be described with the start and end point.

Code Example:

Code:
    public void Lines()
    {
        GL11.glLineWidth(2); //sets the line width to 2 ppt
        GL11.glEnable(GL11.GL_LINE_SMOOTH); //enables line smoothing. I am going to explain GL constants and enabling
        //and disabling later
        GL11.glDisable(GL11.GL_LINE_SMOOTH); //deactivates line smoothing

        GL11.glBegin(GL11.GL_LINE);
        {
            /**
             * one single Line, that will be drawn between 2 vertices
             */
            GL11.glVertex3d(0D, 0D, 0D);
            GL11.glVertex3d(0D, 5D, 0D);
        }
        GL11.glEnd();

        GL11.glBegin(GL11.GL_LINES);
        {
            /**
             * a n-number of lines (n element of natural numbers), where the end and start points will be connected
             * e.g. point one connects to point two - one line. point three connects to point four . second line. and so on
             * the two lines are independent
             */
            GL11.glVertex3f(-1,0,0);
            GL11.glVertex3f(0,1,0);
            GL11.glVertex3f(1,0,0);
            GL11.glVertex3f(-1,0,0);
        }
        GL11.glEnd();
    }

LineStrip
A Line strip is like drawing gl_Lines. The only difference is that the end point of the previous line will be the start point of the following line.

Code:
    public void LineStrip()
    {
        GL11.glBegin(GL11.GL_LINE_STRIP);
        {
            //there will be n-1 lines drawn (where n = number of vertices)
            GL11.glVertex3f(-1,0,0);
            GL11.glVertex3f(0,1,0);
            GL11.glVertex3f(1,0,0);
            GL11.glVertex3f(-1,0,0);
            /**
             * in comparison to gl_Lines, every Vertex, except the first and the last one are connected to two lines.
             */
        }
        GL11.glEnd();
    }

LineLoop
The only difference between a LineLoop and a LineStrip is, that the first and the last vertix will automatically be connected by a line.
Due to this, the LineLoop is often used to draw circles and other round objects (since you can't actually draw anything round in openGL, just incredibly small sides of polygons)

Code:
public void LineStrip()
    {
        double x1 = 0; // x coordinate of the circle
        double y1 = 0; // y coordinate of the circle
        double radius = 5; // the circle's radius
        double x2; // the current x coordinate on the circle's line
        double y2; // the current y coordinate on the circle's line

        GL11.glBegin(GL11.GL_LINE_LOOP);
        {
            for (int i = 0; i <= 360 /*360 degrees for a circle*/ ; i++)
            {
        x2 = Math.sin((i * Math.PI / 180)) * radius;
        y2 = Math.cos((i * Math.PI / 180)) * radius;
        /**
      * take a look at the unity circle and cos and sin in dependency of it, if you don't understand this
      * this will draw an unfilled circle
      */
        GL11.glVertex2d(x1 + x2, y1 + y2);
      }
        }
  GL11.glEnd();
    }

Triangle
in my opinion way easier then the circle, but it is the basic of all geometrical shapes with more than one dimension. You can create many shapes with triangles.
You can replace quads with triangles and you can even draw circles with triangles, but I will show that later.

Code:
public void triangle()
    {
        GL11.glBegin(GL11.GL_TRIANGLES);
        {
            /**
             * the number of vertices has to be n (n element of the natural numbers and a multiple of 3)
             */
            GL11.glVertex3f(-1.0f, -0.5f, 0f);
            GL11.glVertex3f( 1.0f, -0.5f, 0f);
            GL11.glVertex3f( 0.0f,  0.5f, 0f);
            //this was the first triangle
            GL11.glVertex3f(-1.0f, -0.5f, -2f);
            GL11.glVertex3f( 1.0f, -0.5f, -2f);
            GL11.glVertex3f( 0.0f,  0.5f, -2f);
            //this was a second one directly behind it. you can draw an unlimited number of triangles
        }
        GL11.glEnd();
    }

Polygon
There is already a very good explanation of polygon up there .
I recommend using Triangles, where you can, since using GL_Polygon is a very ressource expensive and slow way of drawing Polygons.

Code Example:
Code:
    public void Polygon()
    {
        GL11.glBegin(GL11.GL_POLYGON);
        {
            GL11.glVertex2d(2, 2);
            GL11.glVertex2d(4, 2);
            GL11.glVertex2d(4, 4);
            /**
             * that is basically a triangle drawn as Polygon
             * watch out, only convex polygons will be drawn correctly
             * you can draw any shape with that limitation
             */
        }
        GL11.glEnd();
    }

Quads
You know, what a quad is. The two oppisite sides are perpendicular, it has 4 sides and only angles of 90 degree.
You can draw any quad with triangles. In Minecraft modding, you will mostly use quads for your Guis.
(you can also call it a rectangle)

Code Example:
Code:
public void quads()
    {
        GL11.glBegin(GL11.GL_QUADS);
        {
            /**
             * the number of vertices has to be n (n element of the natural numbers and a multiple of 4)
             */
            GL11.glVertex2d(1, 1);
            GL11.glVertex2d(3, 1);
            GL11.glVertex2d(3, 3);
            GL11.glVertex2d(1, 3);
            //that was the first quad
            GL11.glVertex3d(1, 1, -1);
            GL11.glVertex3d(3, 1, -1);
            GL11.glVertex3d(3, 3, -1);
            GL11.glVertex3d(1, 3, -1);
            //the second quad directly behind the first quad
        }
        GL11.glEnd();
    }

QuadStrip
a quad strip is the same as quads with the difference, that the two last defined verteces of the previous quad will be the first two verteces of the followong quad.
It behaves the same way, Line_Strip behaves to Lines.

Code Example:
Code:
    public void triangle()
    {
        GL11.glBegin(GL11.GL_QUADS);
        {
            /**
             * the number of vertices has to be n (n = 4 + ((k - 1) * 2), k is the number of quads and element of the natural numbers)
             */
            GL11.glVertex2d(1, 1);
            GL11.glVertex2d(3, 1);
            GL11.glVertex2d(3, 3);
            GL11.glVertex2d(1, 3);
            //that was the first quad
            GL11.glVertex2d(6, 3);
            GL11.glVertex2d(6, 1);
            //the second quad directly next to the first quad
        }
        GL11.glEnd();
    }

TriangleStrip
The Triangle_Strip behaves like all the other strips and shares one side with its neighbour.
One annotation: this is the fastest way, to render shapes in OpenGL, so prefer this over anything else. If you know how to use this, use it instead of quads, polygons etc.

Code Example:
Code:
public void triangleStrip()
    {
        GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
        {
            GL11.glVertex3f(-1,0,0);
            GL11.glVertex3f(0,1,0);
            GL11.glVertex3f(1,0,0);
            //that was the first triangle
            GL11.glVertex3f(2,1,0);
            //now you just need one vertex for each triangle
            GL11.glVertex3f(3,0,0);
            //and the third triangle
        }
        GL11.glEnd();
    }

TriangleFan
It is the same as the Triangle Strip, the only difference is, that the 1st and last Triangle will share an edge.
This is also a very fast way of drawing in OpenGL.
You can draw a filled circle by using the TriangleFan. Credits to LulzFTW for the idea.

Code Example:
Code:
public void triangleFan()
    {
        /**
         * this is actually the same as the Line Loop, so look there for a full commented version
         */
        double radius = 5;

        GL11.glBegin(GL11.GL_TRIANGLE_FAN);
  for (int i = 0; i <= 360; i++) {
    double x2 = Math.sin((i * Math.PI / 180)) * radius;
    double y2 = Math.cos((i * Math.PI / 180)) * radius;
    GL11.glVertex2d(4 + x2, 4 + y2);
  }
  GL11.glEnd();
    }

Errors:
GL_INVALID_ENUM is thrown, when an invalid value is entered.

GL_INVALID_OPERATION is thrown, if another glBegin() is called within a glBegin()

GL_INVALID_OPERATION is thrown, if elEnd() is called, if it is called without glBegin()

GL_INVALID_OPERATION is thrown, if another method then glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, glEdgeFlag, glCallList or glCallLists is called between glBegin() and glEnd()

Colors


In OpenGL, every vertex can have an own color. That's for example, how you create gradient triangles and rects.
These colors are defined with 4 double values. The first three being red, green and blue (RGB) and the last one being the alpha channel (RGBA).
Red, Green and Blue are self explanatory, the Aplha channel just describes the transparancy of the color.

The values of the colors will be from 0 to 1.

Code Example
Code:
    public void Colors()
    {
        GL11.glBegin(GL11.GL_QUADS);
        {
            GL11.glColor3f(1, 0, 0); GL11.glVertex3f(0, 0, 0); //red
            GL11.glColor3f(0, 1, 0); GL11.glVertex3f(1, 0, 0); //green
            GL11.glColor3f(0, 0, 1); GL11.glVertex3f(1, 1, 0); //blue
            GL11.glColor3f(1, 1, 0); GL11.glVertex3f(0, 1, 0); //red/green mix
            //now every vertex of this quad has a different color
        }
        GL11.glEnd();
    }

GLEnable and GLDisable


With GLEnable you can configure, how OpenGL will draw you shapes. There is a full documenation, on what everyone does on their website
http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml

Some important Enums:

GL_ALPHA_TEST
this tests for the Aplha channel, what means, it actually activates transparancy. If this is not activated, your alpha channel won't be recognized and set to 1.
GL_DEPTH_TEST
If you draw two objects behind each other, they actually will be behind each other.
GL_LINE_SMOOTH
Smooths your Lines. That is important, if you want to use it for Guis. It will looks way better

That is all. This is some basic OpenGL stuff. I will probably do more, when I have time.
Wrong section? It was requested here!
Any criticism is welcome.

Since this is a scientific work. My relevant resources:

http://wiki.delphigl.com/index.php/glColor
http://wiki.delphigl.com/index.php/glBegin
http://en.wikibooks.org/wiki/OpenGL_Prog...sics/Color
http://en.wikibooks.org/wiki/OpenGL_Prog.../2DObjects
http://www.opengl-forum.de/OpenGLForum/t...97a91a4e#2
http://www.cg.tuwien.ac.at/studentwork/V...chapt4.htm
http://sabia.tic.udc.es/gc/practicas/ope...lBegin.htm
http://www.authenticsociety.com/about/Op...s_glVertex
http://www.opengl.org/wiki/Vertex_Specification
http://www.opentk.com/doc/chapter/2/open...try/vertex
http://www.opentk.com/doc/chapter/2/open...primitives
http://www.youtube.com/watch?v=qniXE1wi0Po
http://www.falloutsoftware.com/tutorials/gl/gl3.htm
http://www.codeworx.org/opengl_tuts.php
http://www.blitzbasic.com/Community/post...opic=42662
http://de.wikipedia.org/wiki/OpenGL
http://en.wikipedia.org/wiki/Polytope
http://en.wikipedia.org/wiki/Polygon
http://trevinca.ei.uvigo.es/~formella/do...de102.html

I, know, I, am, using, too, many, commas,,,,,,,,

1 comment:

  1. I think at the time math is very difficult subject, parents should help kids in solving math problems. and about 12 sided I want to share a simple definition as-12 sided polygon is called as dodecagon, This is one type of regular polygons, it may be regular or irregular. It’s a 12 sided closed figure.
    What is a Regular Polygon

    ReplyDelete

CEX.io