Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Procedure display is responsible for the actual drawing.</p> <pre><code>void display() { </code></pre> <p>This line clears the <em>buffer</em>; the buffer is basically the memory are where the image is rendered; it is basically a matrix with width and height 600x600. To <em>clear</em> means to set every cell of the matrix to the same value. Every cell is a <em>pixel</em> and contains a <em>color</em> and a <em>depth</em>. With this call you are telling OpenGL to paint everything opaque black, and to reset the depth to 1. Why opaque black? Because of your call to <strong>glClearColor</strong>: the first three parameters are the red, green and blue component, and they can range between 0 and 1. 0,0,0 means black. For the last component you specified 1, which means opaque; 0 would be transparent. This last component is called <em>alpha</em> and is used when <em>alpha blending</em> is enabled. Why the clear depth is 1? Because 1 is the default, and you didn't call <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepth.xml" rel="nofollow noreferrer">glClearDepth</a> to override that value.</p> <pre><code> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); </code></pre> <p>This is telling OpenGL that you want to draw quadrilaterals.</p> <pre><code> glBegin(GL_QUADS); </code></pre> <p>You want these quadrilateral to be red (remember that the first component of a color is red).</p> <pre><code> glColor3f(1, 0, 0); // NOT SURE WHERE THIS STARTS, AND HOW THE COORDINATES WORK </code></pre> <p>Now you list the vertices of the quadrilateral (it's only one, four vertices); all vertices will be red because you never update the color by calling <strong>glColor3f</strong>; you can associate a different color to every vertex, the final result is usually very cute if you pick red (1,0,0), green (0,1,0), blue (0,0,1) and white (1,1,1); this quadrilateral should appear to screen as a square, because it is a square geometrically, your window is a square, and the camera (defined with <strong>glOrtho</strong>) has a square aspect (first four parameters of the call to <strong>glOrtho</strong>). If you didn't call <strong>glOrtho</strong> you would probably see only red, because the default OpenGL coordinates range between -1 and 1 and so you are covering the entire window.</p> <pre><code> glVertex2f(-1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); glVertex2f( 1.0f,-1.0f); glVertex2f(-1.0f,-1.0f); </code></pre> <p>This means that you are done with drawing.</p> <pre><code> glEnd(); </code></pre> <p>Technically, it may be that OpenGL didn't send any of the commands you specified to the graphic card; commands may be enqueued for efficiency reason. Calling <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlush.xml" rel="nofollow noreferrer">glFlush</a> forces the command to be sent to the graphic card.</p> <pre><code> glFlush(); } </code></pre> <p>You wrote this function, <em>init</em> to initialize some of the OpenGL <em>states</em>, that you felt would remain stable across the application. In reality a real application like a game would have most of this stuff under display. For instance a game must continuously update the camera, as the player moves.</p> <pre><code>void init() { </code></pre> <p>Here as we said before you are setting the clear color to be opaque black.</p> <pre><code> glClearColor(0.0, 0.0, 0.0, 1.0); </code></pre> <p>Here you are saying that the camera is not of a perspective type; basically things that are far away don't get smaller. It is similar to the view that an artificial satellite has of a city. In particular you are creating a camera which is not "centered" on the field of view: I recommend to use a call like <strong>glOrtho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0)</strong> for your first experiments. For a non perspective camera the coordinates that you specify here override the convention -1 to +1 that we mentioned above. Try to regulate the parameters such that your red square appears small, and centered.</p> <pre><code> glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, 10.0, 0, 10.0, -1.0, 1.0); //What does this do and how does it's coordinates work? </code></pre> <p>Here you are basically positioning the camera relative to the square, or the square relative to the camera; there are infinite ways to see it. You are defining a geometrical transformation, and the reason why it is called MODELVIEW is that it is not uniquely something that alters the <em>model</em> (the square) or the <em>view</em> (the camera) but both, depending on the way you see it. However, your square appears rotated because you are calling <a href="http://www.khronos.org/opengles/sdk/1.1/docs/man/glRotate.xml" rel="nofollow noreferrer">glRotatef</a>; remove it and the square should appear like a square.</p> <pre><code> glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(30.0, 1.0, 1.0, 1.0); </code></pre> <p>Depth test is a technique that uses the depth store in the buffer in order to remove hidden surfaces, for instance the back faces of a cube in a 3D scene. Your scene is 2D and you are drawing only a quad, so this is really non affecting your drawing.</p> <pre><code> glEnable(GL_DEPTH_TEST); } </code></pre> <p>In the <strong>main</strong> you are interacting with <em>glut</em>, an optional subsystem which is not part of OpenGL but is useful to carry out some boring and tedious operations that only the operating system is authorized to perform.</p> <pre><code>int main(int argc, char *argv[]) { </code></pre> <p>First you must init <em>glut</em>.</p> <pre><code> glutInit(&amp;argc, argv); </code></pre> <p>Then you define the window that will contain your rendering image.</p> <pre><code> glutInitWindowSize(600, 600); glutInitWindowPosition(250, 250); </code></pre> <p>GLUT_RGB means that your window only supports red, green and blue, and doesn't have an alpha channel (this is very often the case). GLUT_DEPTH means that your buffer will be able to store the depth of each pixel. GLUT_SINGLE means that the window is single buffered, that is your commands will directly draw on the window; another option is double buffering, where you actually draw on a <em>back</em> buffer, and then you swap <em>front</em> and back buffer so that the rendered image appears suddenly, and not in a progressive fashion. Your scene is so simple that you shouldn't notice any difference between GLUT_SINGLE and GLUT_DOUBLE.</p> <pre><code> glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH); </code></pre> <p>Then you actually create the window.</p> <pre><code> glutCreateWindow("Model View"); </code></pre> <p>You tell glut which function should be called to render the scene.</p> <pre><code> glutDisplayFunc(display); </code></pre> <p>Here you call your <strong>init</strong> function.</p> <pre><code> init(); </code></pre> <p>This is a window loop, provided by glut. Most windowing system require a software loop in order to keep the window alive, and able to respond to clicks, drags, resize and keyboard strokes.</p> <pre><code> glutMainLoop(); return 0; } </code></pre> <p>Long story short, several versions of OpenGL are available, and they can be programmed using several languages, and targeted to several platforms. The single most important difference between these versions is that some use a <em>fixed function pipeline</em> (FFP) whereas the newest versions have a <em>programmable pipeline</em>. Your program uses a fixed function pipeline. You should switch to a programmable pipeline whenever you can, because it is the modern way of doing computer graphics, and is <em>much</em> more flexible, even though it requires a little more programming, as the name suggests. </p> <p>You should ignore the tutorials that I linked originally, I didn't immediately realized how outdated they were. You should go with <a href="https://stackoverflow.com/questions/14822763/opengl-why-is-my-rectangle-so-big-and-tilted/#comment20779347_14823324">the one recommended by datenwolf</a> or, if you are interested in mobile development, you could consider learning OpenGL ES <strong>2</strong> (the 2 is important, because the previous version was fixed function). There is also a variant of OpenGL ES 2 for HTML5 and Javascript, called WebGL. You find the tutorials <a href="http://learningwebgl.com/" rel="nofollow noreferrer">here</a>, together with a ZIP file containing all the examples; I use their codebase whenever I need to check if I understood a new concept.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload