Jason McKesson avatar Jason McKesson committed c689e4d

Upgraded tutorials to GL 3.0. Tested and confirmed working. Upgraded documentation to match.

Comments (0)

Files changed (42)

Documents/Basics/Tutorial 01.xml

 glUseProgram(theProgram);
 
 glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-glEnableVertexAttribArray(positionAttrib);
-glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+glEnableVertexAttribArray(0);
+glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 glDrawArrays(GL_TRIANGLES, 0, 3);
 
-glDisableVertexAttribArray(positionAttrib);
+glDisableVertexAttribArray(0);
 glUseProgram(0);
 
 glutSwapBuffers();</programlisting>
                 there is vertex data in this buffer object.</para>
             <para>We do this in the rendering code. That is the purpose of these lines:</para>
             <programlisting>glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-glEnableVertexAttribArray(positionAttrib);
-glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);</programlisting>
+glEnableVertexAttribArray(0);
+glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);</programlisting>
             <para>The first function we have seen before. It simply says that we are going to use
                 this buffer object.</para>
             <para>The second function, <function>glEnableVertexAttribArray</function> is something
-                we will explain in the next section, when we talk about where
-                    <varname>positionAttrib</varname> comes from. Suffice it to say that this
-                function tells OpenGL that the vertex data called <varname>positionAttrib</varname>
-                will be provided in rendering calls. Without this function, the next one is
+                we will explain in the next section. Without this function, the next one is
                 unimportant.</para>
             <para>The third function is the real key. <function>glVertexAttribPointer</function>,
                 despite having the word <quote>Pointer</quote> in it, does not deal with pointers.
                 function is called is the buffer object that will be associated with this piece of
                 data.</para>
             <para>What this particular function call is saying is this. <quote>The piece of vertex
-                    data called <varname>positionAttrib</varname> comes from the buffer object
+                    data indexed 0 comes from the buffer object
                         <varname>positionBufferObject</varname>. This piece of vertex data contains
                     32-bit float values, and each piece is a sequence of 4 of them. The data starts
                     at the 0th byte of the buffer object, and each set of 4 32-bit floats is tightly
                 forbidden). This is what our simple vertex shader looks like:</para>
             <example>
                 <title>Vertex Shader</title>
-                <programlisting>#version 150
+                <programlisting>#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 void main()
 {
     gl_Position = position;
 }</programlisting>
             </example>
             <para>This looks fairly simple. The first line states that the version of GLSL used by
-                this shader is version 1.50. A version declaration is required for all GLSL
+                this shader is version 3.30. A version declaration is required for all GLSL
                 shaders.</para>
             <para>The next line defines an input to the vertex shader. The input is called
                     <varname>position</varname> and is of type <type>vec4</type>: a 4-dimensional
-                vector of floating-point values.</para>
+                vector of floating-point values. It also has a layout location of 0; we'll explain
+                that a little later.</para>
             <para>As with C, a shader's execution starts with the <function>main</function>
                 function. This shader is very simple, copying the input <varname>position</varname>
                 into something called <varname>gl_Position</varname>. This is a variable that is
             <formalpara>
                 <title>Vertex Attributes</title>
                 <para>Inputs to and outputs from a shader stage come from somewhere and go to
-                    somewhere. Thus, the input <varname>position</varname> must be filled in with
-                    data somewhere. So where does that data come from? Inputs to a vertex shader are
-                    called <glossterm>vertex attributes</glossterm>.</para>
+                    somewhere. Thus, the input <varname>position</varname> in the vertex shader must
+                    be filled in with data somewhere. So where does that data come from? Inputs to a
+                    vertex shader are called <glossterm>vertex attributes</glossterm>.</para>
             </formalpara>
             <para>You might recognize something similar to the term <quote>vertex attribute.</quote>
                 For example, <quote>glEnable<emphasis>VertexAttrib</emphasis>Array</quote> or
                     <varname>glVertexAttribPointer</varname>. This function describes where the data
                 for an attribute comes from. The connection between a particular call to
                     <function>glVertexAttribPointer</function> and the string name of an input value
-                to a vertex shader is somewhat complicated. This is where that mysterious variable,
-                    <varname>positionAttrib,</varname> comes into play.</para>
-            <para>The details of compiling a shader will be gone over a bit later, but the
-                connection is made with this call:</para>
-            <programlisting>positionAttrib = glGetAttribLocation(theProgram, "position");</programlisting>
-            <para>The variable <varname>theProgram</varname> represents the vertex shader (and the
-                fragment shader, but that's for later). The function
-                    <function>glGetAttribLocation</function> takes the given string that specifies a
-                vertex input, and it returns a number that represents that particular input. This
-                number is then used in subsequent <function>glVertexAttribPointer</function> calls
-                and the like to represent the attribute for <quote>position.</quote></para>
+                to a vertex shader is somewhat complicated.</para>
+            <para>Each attribute variable, an input to a vertex shader, has an index location called
+                an <glossterm>attribute index</glossterm>. The input in this shader was defined with
+                this statement:</para>
+            <programlisting>layout(location = 0) in vec4 position;</programlisting>
+            <para>The layout location part assigns the attribute index of 0 to
+                    <varname>position</varname>. Attribute indices must be positive numbers, and
+                there is a hardware-based limit on the number of attribute indices that can be in
+                use at any one time.</para>
+            <para>In code, when referring to attributes, they are <emphasis>always</emphasis>
+                referred to by attribute index. The functions
+                    <function>glEnableVertexAttribArray</function>,
+                    <function>glDisableVertexAttribArray</function>,  and
+                    <function>glVertexAttribPointer</function> all take as their first parameter an
+                attribute index. We assigned the attribute index of the <varname>position</varname>
+                attribute to 0 in the vertex shader, so the call to
+                    <function>glEnableVertexAttribArray(0)</function> enables the attribute index
+                for the <varname>position</varname> attribute.</para>
         </section>
         <section>
             <title>Rasterization</title>
             <title>Fragment Processing</title>
             <para>A fragment shader is used to compute the output color(s) of a fragment. The inputs
                 of a fragment shader include the window-space XYZ position of the fragment. It can
-                also include user-defined data, but we will get to that.</para>
+                also include user-defined data, but we will get to that in later tutorials.</para>
             <para>Our fragment shader looks like this:</para>
             <example>
                 <title>Fragment Shader</title>
-                <programlisting>#version 150
+                <programlisting>#version 330
 
 out vec4 outputColor;
 void main()
 }</programlisting>
             </example>
             <para>As with the vertex shader, the first line states that the shader uses GLSL version
-                1.50.</para>
+                3.30.</para>
             <para>The next line specifies an output for the fragment shader. The output variable is
                 of type <type>vec4</type>.</para>
             <para>The main function simply sets the output color to a 4-dimensional vector, with all
                 of the components as 1.0f. This sets the Red, Green, and Blue components of the
                 color to full intensity, which is 1.0; this creates the white color of the triangle.
                 The fourth component is something we will see in later tutorials.</para>
-            <para>This fragment shader does not do anything with the position input.</para>
+            <para>Though all fragment shaders are provided the window-space position of the
+                fragment, this one does not need it. So it simply does not use it.</para>
             <para>After the fragment shader executes, the fragment output color is written to the
                 output image.</para>
+            <note>
+                <para>In the section on vertex shaders, we had to use the <literal>layout(location =
+                        #)</literal> syntax in order to provide a connection between a vertex shader
+                    input and a vertex attribute index. This was required in order for the user to
+                    connect a vertex array to a vertex shader input. So you may be wondering where
+                    the connection between the fragment shader output and the screen comes
+                    in.</para>
+                <para>OpenGL recognizes that, in a lot of rendering, there is only one logical place
+                    for a fragment shader output to go: the current image being rendered to (in our
+                    case, the screen). Because of that, if you define only one output from a
+                    fragment shader, then this output value will automatically be written to the
+                    current destination image. It is possible to have multiple fragment shader
+                    outputs that go to multiple different destination images; this adds some
+                    complexity, similar to attribute indices. But that is for another time.</para>
+            </note>
         </section>
     </section>
     <section>
     shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
     
     theProgram = CreateProgram(shaderList);
-    
-    positionAttrib = glGetAttribLocation(theProgram, "position");
 }</programlisting>
         </example>
         <para>The first statement simply creates a list of the shader objects we intend to link
             linking status by calling <function>glGetProgramiv</function> with
                 <literal>GL_LINK_STATUS</literal>. If it is GL_FALSE, then the linking failed and we
             print the linking log. Otherwise, we return the created program.</para>
-        <formalpara>
-            <title>Vertex Attribute Indexes</title>
-            <para>The last line of <function>InitializeProgram</function> is the key to how
-                attributes are linked between the vertex array data and the vertex program's
-                input.</para>
-        </formalpara>
-        <programlisting>positionAttrib = glGetAttribLocation(theProgram, "position");</programlisting>
-        <para>The function <function>glGetAttribLocation</function> takes a successfully linked
-            program and a string naming one of the inputs of the vertex shader in that program. It
-            returns the attribute index of that input. Therefore, when we use this program, if we
-            want to send some vertex data to the <varname>position</varname> input variable, we
-            simply use the <varname>positionAttrib</varname> value we retrieved from
-                <function>glGetAttribLocation</function> in our call to
-                <function>glVertexAttribPointer</function>.</para>
+        <note>
+            <para>In the above shaders, the attribute index for the vertex shader input
+                    <varname>position</varname> was assigned directly in the shader itself. There
+                are other ways to assign attribute indices to attributes besides
+                    <literal>layout(location = #)</literal>. OpenGL will even assign an attribute
+                index if you don't use any of them. Therefore, it is possible that you may not know
+                the attribute index of an attribute. If you need to query the attribute index, you
+                may call <function>glGetAttribLocation</function> with the program object and a
+                string containing the attribute's name.</para>
+        </note>
         <formalpara>
             <title>Using Programs</title>
             <para>To tell OpenGL that rendering commands should use a particular program object, the
     <section>
         <?dbhtml filename="Tut01 Cleanup.html" ?>
         <title>Cleanup</title>
-        <para>The tutorial allocates a lot of system resources. It allocates a buffer object, which
-            represents memory on the GPU. It creates two shader objects and a program object. But it
-            never explicitly deletes any of this.</para>
+        <para>The tutorial allocates a lot of OpenGL resources. It allocates a buffer object, which
+            represents memory on the GPU. It creates two shader objects and a program object, all of
+            which stored in memory owned by OpenGL. But it never explicitly deletes any of
+            this.</para>
         <para>Part of this is due to the nature of FreeGLUT, which does not provide hooks for a
             cleanup function. But part of it is also due to the nature of OpenGL itself. In a simple
             example such as this, there is no need to delete anything. OpenGL will clean up its own
                 </glossdef>
             </glossentry>
             <glossentry>
+                <glossterm>attribute index</glossterm>
+                <glossdef>
+                    <para>Each input variable in a vertex shader must be assigned an index number.
+                        This number is used in code to refer to that particular attribute. This
+                        number is the attribute index.</para>
+                </glossdef>
+            </glossentry>
+            <glossentry>
                 <glossterm>viewport transform</glossterm>
                 <glossdef>
                     <para>The process of transforming vertex data from normalized device coordinate

Documents/Basics/Tutorial 02.xml

             one in the last tutorial. The fragment shader is very new, however:</para>
         <example>
             <title>FragPosition's Fragment Shader</title>
-            <programlisting><![CDATA[#version 150
+            <programlisting><![CDATA[#version 330
 
 out vec4 outputColor;
 
     glUseProgram(theProgram);
     
     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-    glEnableVertexAttribArray(positionAttrib);
-    glEnableVertexAttribArray(colorAttrib);
-    glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-    glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);
+    glEnableVertexAttribArray(0);
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);
     
     glDrawArrays(GL_TRIANGLES, 0, 3);
     
-    glDisableVertexAttribArray(positionAttrib);
-    glDisableVertexAttribArray(colorAttrib);
+    glDisableVertexAttribArray(0);
+    glDisableVertexAttribArray(1);
     glUseProgram(0);
     
     glutSwapBuffers();
             <para>Our new vertex shader looks like this:</para>
             <example>
                 <title>Multi-input Vertex Shader</title>
-                <programlisting><![CDATA[#version 150
+                <programlisting><![CDATA[#version 330
 
-in vec4 position;
-in vec4 color;
+layout (location = 0) in vec4 position;
+layout (location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 
             <para>The declaration of the global <varname>color</varname> defines a new input for the
                 vertex shader. So this shader, in addition to taking an input named
                     <varname>position</varname> also takes a second input named
-                    <varname>color</varname>. As with the <varname>position</varname> input, the
-                tutorial queries the attribute location after the program is linked with the
-                    <function>glGetAttribLocation</function>:</para>
-            <example>
-                <title>Querying the Attributes</title>
-                <programlisting>positionAttrib = glGetAttribLocation(theProgram, "position");
-colorAttrib = glGetAttribLocation(theProgram, "color");</programlisting>
-            </example>
-            <para>The <varname>colorAttrib</varname> variable is used later when defining the
-                attribute arrays for rendering.</para>
+                    <varname>color</varname>. As with the <varname>position</varname> input, this
+                tutorial assigns each attribute to an attribute index. <varname>position</varname>
+                is assigned the attribute index 0, while <varname>color</varname> is assigned
+                1.</para>
             <para>That much only gets the data into the vertex shader. We want to pass this data out
                 of the vertex shader. To do this, we must define an <glossterm>output
                     variable</glossterm>. This is done using the <literal>out</literal> keyword. In
             <para>The new fragment shader looks like this:</para>
             <example>
                 <title>Fragment Shader with Input</title>
-                <programlisting><![CDATA[#version 150
+                <programlisting><![CDATA[#version 330
 
 smooth in vec4 theColor;
 
             <para>The fragment shader is not run 3 times. It is run once for every fragment produced
                 by the rasterizer for this triangle. The number of fragments produced by a triangle
                 depends on the viewing resolution and how much area of the screen the triangle
-                covers. An equilateral triangle the length of who's sides is 1 has an area of
+                covers. An equilateral triangle the length of who's sides are 1 has an area of
                 ~0.433. The total screen area (on the range [-1, 1] in X and Y) is 4, so our
                 triangle covers approximately one-tenth of the screen. The window's natural
                 resolution is 500x500 pixels. 500*500 is 250,000 pixels; one-tenth of this is
                 alternatives: <literal>noperspective</literal> and <literal>flat</literal>.</para>
             <para>If you were to modify the tutorial and change <literal>smooth</literal> to
                     <literal>noperspective</literal>, you would see no change. That does not mean a
-                change did not happen; our example is too simple for there to actually be a change.
-                The difference between <literal>smooth</literal> and
-                    <literal>noperspective</literal> is subtle, and only matters once we start using
-                more concrete and real tutorials. We will discuss this different much later.</para>
+                change did not happen; our example is just too simple for there to actually be a
+                change. The difference between <literal>smooth</literal> and
+                    <literal>noperspective</literal> is somewhat subtle, and only matters once we
+                start using more concrete and real tutorials. We will discuss this different much
+                later.</para>
             <para>The <literal>flat</literal> interpolation actually turns interpolation off. It
                 essentially says that, rather than interpolating between three values, each fragment
                 of the triangle will simply get the first of the three vertex shader output
                 </listitem>
             </itemizedlist>
         </section>
+        <section>
+            <title>GLSL Functions of Note</title>
+            <funcsynopsis>
+                <funcprototype>
+                    <funcdef>vec <function>mix</function></funcdef>
+                    <paramdef>vec <parameter>initial</parameter></paramdef>
+                    <paramdef>vec <parameter>final</parameter></paramdef>
+                    <paramdef>float <parameter>alpha</parameter></paramdef>
+                </funcprototype>
+                <funcprototype>
+                    <funcdef>vec <function>mix</function></funcdef>
+                    <paramdef>vec <parameter>initial</parameter></paramdef>
+                    <paramdef>vec <parameter>final</parameter></paramdef>
+                    <paramdef>vec <parameter>alpha</parameter></paramdef>
+                </funcprototype>
+            </funcsynopsis>
+            <para>Performs a linear interpolation between <parameter>initial</parameter>,
+                    <parameter>final</parameter>, based on <parameter>alpha</parameter>. An
+                    <parameter>alpha</parameter> value of 0 means that the
+                    <parameter>inital</parameter> value is returned, while an
+                    <parameter>alpha</parameter> of 1 means the <parameter>final</parameter> value
+                is returned. The <type>vec</type> type means that the parameter can be a vector or
+                    <type>float</type>. All occurrences of <type>vec</type> must be the same in a
+                particular function call, however, so <parameter>initial</parameter> and
+                    <parameter>final</parameter> must have the same type.</para>
+            <para>The <parameter>alpha</parameter> value can be either a scalar or a vector of the
+                same length as <parameter>initial</parameter> and <parameter>final</parameter>. If
+                it is a scalar, then all of the components of the two values are interpolated by
+                that scalar. If it is a vector, then the components of
+                    <parameter>initial</parameter> and <parameter>final</parameter> are interpolated
+                by their corresponding components of <parameter>alpha</parameter>.</para>
+            <para>If <parameter>alpha</parameter>, or any component of <parameter>alpha</parameter>,
+                is outside of the range [0, 1], then the return value of this function is
+                undefined.</para>
+        </section>
     </section>
     <section xml:id="Tut02_Glossary">
         <?dbhtml filename="Tut02 Glossary.html" ?>

Documents/Positioning/Tutorial 03.xml

     glUseProgram(theProgram);
     
     glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-    glEnableVertexAttribArray(positionAttrib);
-    glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
     
     glDrawArrays(GL_TRIANGLES, 0, 3);
     
-    glDisableVertexAttribArray(positionAttrib);
+    glDisableVertexAttribArray(0);
     glUseProgram(0);
     
     glutSwapBuffers();
             vertex shader used here is as follows:</para>
         <example>
             <title>Offsetting Vertex Shader</title>
-            <programlisting>#version 150
+            <programlisting>#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 uniform vec2 offset;
 
 void main()
             variables defined as <literal>in</literal>. Input variables change with every execution
             of the shader. Uniform variables (called <glossterm>uniforms</glossterm>) change only
             between executions of rendering calls. And even then, they only change when the user
-            sets them explicitly to a value. </para>
+            sets them explicitly to a new value. </para>
         <para>Vertex shader inputs come from vertex attribute array definitions and buffer objects.
             By contrast, uniforms are set directly on program objects.</para>
         <para>In order to set a uniform in a program, we need two things. The first is a uniform
-            location. Much like with attributes, you must get an index that refers to the uniform
-            name. In this tutorial, this is done in the <function>InitializeProgram</function>
-            function, with this line:</para>
+            location. Much like with attributes, there is an index that refers to a specific uniform
+            value. Unlike attributes, you cannot set this location yourself; you must query it. In
+            this tutorial, this is done in the <function>InitializeProgram</function> function, with
+            this line:</para>
         <programlisting>offsetLocation = glGetUniformLocation(theProgram, "offset");</programlisting>
         <para>The function <function>glGetUniformLocation</function> retrieves the uniform location
-            for the uniform named by the second parameter. Note that, just because a uniform is
+            for the uniform named by the second parameter. Note that just because a uniform is
             defined in a shader, GLSL does not <emphasis>have</emphasis> to provide a location for
-            it. It will only if the uniform is actually used in the program, as we see in the vertex
-            shader.</para>
+            it. It will only have a location if the uniform is actually used in the program, as we
+            see in the vertex shader; <function>glGetUniformLocation</function> will return -1 if
+            the uniform has no location.</para>
         <para>Once we have the uniform location, we can set the uniform's value. However, unlike
             retrieving the uniform location, setting a uniform's value requires that the program be
             currently in use with <function>glUseProgram</function>. Thus, the rendering code looks
     glUniform2f(offsetLocation, fXOffset, fYOffset);
     
     glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-    glEnableVertexAttribArray(positionAttrib);
-    glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
     
     glDrawArrays(GL_TRIANGLES, 0, 3);
     
-    glDisableVertexAttribArray(positionAttrib);
+    glDisableVertexAttribArray(0);
     glUseProgram(0);
     
     glutSwapBuffers();
         <para>The vertex program is found in <filename>data\calcOffset.vert</filename>.</para>
         <example>
             <title>Offset Computing Vertex Shader</title>
-            <programlisting>#version 150
+            <programlisting>#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 uniform float loopDuration;
 uniform float time;
 
     glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
     
     glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-    glEnableVertexAttribArray(positionAttrib);
-    glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
     
     glDrawArrays(GL_TRIANGLES, 0, 3);
     
-    glDisableVertexAttribArray(positionAttrib);
+    glDisableVertexAttribArray(0);
     glUseProgram(0);
     
     glutSwapBuffers();
     
     theProgram = Framework::CreateProgram(shaderList);
     
-    positionAttrib = glGetAttribLocation(theProgram, "position");
     elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
     
     GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
                 <filename>data\calcColor.frag</filename>:</para>
         <example>
             <title>Time-based Fragment Shader</title>
-            <programlisting>#version 150
+            <programlisting>#version 330
 
 out vec4 outputColor;
 
     
     theProgram = Framework::CreateProgram(shaderList);
 
-    positionAttrib = glGetAttribLocation(theProgram, "position");
     elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
     
     GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
                 </glossentry>
             </glosslist>
         </section>
+        <section>
+            <title>GLSL Functions of Note</title>
+            <funcsynopsis>
+                <funcprototype>
+                    <funcdef>vec <function>mod</function></funcdef>
+                    <paramdef>vec <parameter>numerator</parameter></paramdef>
+                    <paramdef>float <parameter>denominator</parameter></paramdef>
+                </funcprototype>
+                <funcprototype>
+                    <funcdef>vec <function>mod</function></funcdef>
+                    <paramdef>vec <parameter>numerator</parameter></paramdef>
+                    <paramdef>vec <parameter>denominator</parameter></paramdef>
+                </funcprototype>
+            </funcsynopsis>
+            <para>The <function>mod</function> function takes the modulus of the
+                    <parameter>numerator</parameter> by the <parameter>denominator</parameter>. The
+                modulus can be thought of as a way of causing a loop; the return value will be on
+                the range [0, <parameter>denominator</parameter>) in a looping fashion.
+                Mathematically, it is defined as <parameter>numerator</parameter> -
+                    (<parameter>denominator</parameter> *
+                    <function>FLOOR</function>(<parameter>numerator</parameter> /
+                    <parameter>denominator</parameter>)), where <function>FLOOR</function> rounds a
+                floating-point value down towards the smallest whole number.</para>
+            <para>The type <type>vec</type> can be either <type>float</type> or any vector type. It
+                must be the same type for all parameters. If a vector denominator is used, then the
+                modulus is taken for each corresponding component. The function returns a vector of
+                the same size as its <parameter>numerator</parameter> type.</para>
+            <funcsynopsis>
+                <funcprototype>
+                    <funcdef>vec <function>cos</function></funcdef>
+                    <paramdef>vec <parameter>angle</parameter></paramdef>
+                </funcprototype>
+                <funcprototype>
+                    <funcdef>vec <function>sin</function></funcdef>
+                    <paramdef>vec <parameter>angle</parameter></paramdef>
+                </funcprototype>
+            </funcsynopsis>
+            <para>Returns the trigonometric <link
+                    xlink:href="http://en.wikipedia.org/wiki/Sine#Sine.2C_cosine_and_tangent">cosine
+                    or sine</link>, respectively, of the given <parameter>angle.</parameter> The
+                    <parameter>angle</parameter> is given in units of radians. If the
+                    <parameter>angle</parameter> is a vector, then the returned vector will be of
+                the same size, and will be the cosine or sine of each component of the
+                    <parameter>angle</parameter> vector.</para>
+        </section>
     </section>
     <section xml:id="Tut03_Glossary">
         <?dbhtml filename="Tut03 Glossary.html" ?>

Documents/Positioning/Tutorial 04.xml

                 this:</para>
             <example>
                 <title>ManualPerspective Vertex Shader</title>
-                <programlisting><![CDATA[#version 150
+                <programlisting><![CDATA[#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 
         <para>The vertex shader is much simpler in this case:</para>
         <example>
             <title>MatrixPerspective Vertex Shader</title>
-            <programlisting><![CDATA[#version 150
+            <programlisting><![CDATA[#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Documents/Positioning/Tutorial 05.xml

   (Pos1, Clr1), (Pos2, Clr2), (Pos3, Clr3),</programlisting>
             <para>12 vertices, which for 4 triangles.</para>
             <note>
-                <para>Each attribute for a vertex uses the <emphasis>same</emphasis> index. That is,
-                    there is only <emphasis>one</emphasis> element array, and the indices fetched
-                    from the array are used for <emphasis>all</emphasis> attributes of the vertex
-                    arrays. So you cannot have an element array for positions and a separate one for
-                    colors; they all have to use the same element array.</para>
+                <para>Each attribute array for a vertex uses the <emphasis>same</emphasis> index.
+                    That is, there is only <emphasis>one</emphasis> element array, and the indices
+                    fetched from the array are used for <emphasis>all</emphasis> attributes of the
+                    vertex arrays. So you cannot have an element array for positions and a separate
+                    one for colors; they all have to use the same element array.</para>
                 <para>This means that there can and often will be some duplication within a
                     particular attribute array. For example, in order to have solid face colors, we
                     will still have to replicate the color for every position of that triangle. And
                     bound to; buffer objects can be bound to multiple targets. So it is perfectly
                     legal to use the same buffer object to store vertex attributes and element
                     arrays (and, FYI, any data for any other use of buffer objects that exists in
-                    OpenGL). Obviously, the different data would be in separate parts of the
+                    OpenGL). Obviously, the different data would be in separate regions of the
                     buffer.</para>
             </note>
             <para>In order to do indexed drawing, we must bind the buffer to
     size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
     
     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-    glEnableVertexAttribArray(positionAttrib);
-    glEnableVertexAttribArray(colorAttrib);
-    glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-    glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+    glEnableVertexAttribArray(0);
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
     
     glBindVertexArray(0);
     colorDataOffset += sizeof(float) * 4 * (numberOfVertices/2);
 
     //Use the same buffer object previously bound to GL_ARRAY_BUFFER.
-    glEnableVertexAttribArray(positionAttrib);
-    glEnableVertexAttribArray(colorAttrib);
-    glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)posDataOffset);
-    glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+    glEnableVertexAttribArray(0);
+    glEnableVertexAttribArray(1);
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)posDataOffset);
+    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
     
     glBindVertexArray(0);
 
 size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-glEnableVertexAttribArray(positionAttrib);
-glEnableVertexAttribArray(colorAttrib);
-glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+glEnableVertexAttribArray(0);
+glEnableVertexAttribArray(1);
+glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 glBindVertexArray(0);</programlisting>
                 the same index data. The more compelling way to use it is with objects that have
                 different index data. Of course, if objects have different index data, you may be
                 wondering why you would bother with BaseVertex when you could just manually add the
-                offset to the index data when you create the element buffer.</para>
+                offset to the indices themselves when you create the element buffer.</para>
             <para>There are several reasons not to do this. One of these is that
                     <literal>GL_UNSIGNED_INT</literal> is twice as large as
-                    <literal>GL_UNSIGNED_SHORT</literal>. If you have more than 65,536 attribute
-                values in an array, whether for one object or for many, you would need to use ints
-                instead of shorts for indices. Using ints can hurt performance, particularly on
-                older hardware with less bandwidth. With BaseVertex, you can use shorts for
-                everything, unless a particular object has more than 65,536 vertices.</para>
+                    <literal>GL_UNSIGNED_SHORT</literal>. If you have more than 65,536 entries in an
+                array, whether for one object or for many, you would need to use ints instead of
+                shorts for indices. Using ints can hurt performance, particularly on older hardware
+                with less bandwidth. With BaseVertex, you can use shorts for everything, unless a
+                particular object itself has more than 65,536 vertices.</para>
             <para>The other reason not to manually bias the index data is to more accurately match
                 the files you are using. When loading indexed mesh data from files, the index data
                 is not biased by a base vertex; it is all relative to the model's start. So it makes

Documents/Tutorials.xml

                 of them go into any real depth in terms of programmability.</para>
             <para>These tutorials are designed first and foremost to <emphasis>teach</emphasis> the
                 reader valuable information about how graphics works. To this end, each and every
-                tutorials will use the OpenGL Shading Language and all modern (as of OpenGL 3.2)
+                tutorials will use the OpenGL Shading Language and all modern (as of OpenGL 3.3)
                 features of the API. This makes it impossible to gloss over seemingly minor yet
                 critical information about how various features of the language and graphics
                 hardware actually work.</para>
             <note>
-                <para>As a side-effect, these tutorials all require OpenGL 3.2-capable hardware and
+                <para>As a side-effect, these tutorials all require OpenGL 3.3-capable hardware and
                     drivers. This means any GeForce 8xxx or better, or any Radeon HD-class card.
                     These are also called <quote>Direct3D 10</quote> cards, but you do not need
                     Windows Vista or 7 to use their advanced features through OpenGL.</para>

Tut 01 Hello Triangle/premake4.lua

 dofile("../framework/framework.lua")
 
 SetupSolution("Tutorial1")
-dofile("tutorials");
+dofile("tutorials.lua");

Tut 01 Hello Triangle/tut1.cpp

 }
 
 GLuint theProgram;
-GLuint positionAttrib;
 
 const std::string strVertexShader(
-	"#version 150\n"
-	"in vec4 position;\n"
+	"#version 330\n"
+	"layout(location = 0) in vec4 position;\n"
 	"void main()\n"
 	"{\n"
 	"   gl_Position = position;\n"
 );
 
 const std::string strFragmentShader(
-	"#version 150\n"
+	"#version 330\n"
 	"out vec4 outputColor;\n"
 	"void main()\n"
 	"{\n"
 	shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader));
 
 	theProgram = CreateProgram(shaderList);
-
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 }
 
 const float vertexPositions[] = {
 	glUseProgram(theProgram);
 
 	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 02 Playing with Colors/FragPosition.cpp

 
 
 GLuint theProgram;
-GLuint positionAttrib;
 GLuint elapsedTimeUniform;
 
 void InitializeProgram()
 	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "FragPosition.frag"));
 
 	theProgram = Framework::CreateProgram(shaderList);
-
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 }
 
 const float vertexData[] = {
 	glUseProgram(theProgram);
 
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 02 Playing with Colors/VertexColors.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 void InitializeProgram()
 {
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
 }
 
 const float vertexData[] = {
 	glUseProgram(theProgram);
 
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
-	glDisableVertexAttribArray(colorAttrib);
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 02 Playing with Colors/data/FragPosition.frag

-#version 150
+#version 330
 
 out vec4 outputColor;
 

Tut 02 Playing with Colors/data/FragPosition.vert

-#version 150
+#version 330
 
-in vec4 position;
+layout (location = 0) in vec4 position;
 
 void main()
 {

Tut 02 Playing with Colors/data/VertexColors.frag

-#version 150
+#version 330
 
 smooth in vec4 theColor;
 

Tut 02 Playing with Colors/data/VertexColors.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout (location = 0) in vec4 position;
+layout (location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Tut 03 OpenGLs Moving Triangle/cpuPositionOffset.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
 
 void InitializeProgram()
 {
 	shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, "standard.frag"));
 
 	theProgram = Framework::CreateProgram(shaderList);
-
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 }
 
 const float vertexPositions[] = {
 	glUseProgram(theProgram);
 
 	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 03 OpenGLs Moving Triangle/data/calcOffset.vert

-#version 150
+#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 uniform float loopDuration;
 uniform float time;
 

Tut 03 OpenGLs Moving Triangle/data/positionOffset.vert

-#version 150
+#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 uniform vec2 offset;
 
 void main()

Tut 03 OpenGLs Moving Triangle/data/standard.frag

-#version 150
+#version 330
 
 out vec4 outputColor;
 

Tut 03 OpenGLs Moving Triangle/data/standard.vert

-#version 150
+#version 330
 
-in vec4 position;
+layout(location = 0) in vec4 position;
 
 void main()
 {

Tut 03 OpenGLs Moving Triangle/fragChangeColor.cpp

 #include "../framework/framework.h"
 
 GLuint theProgram;
-GLuint positionAttrib;
 GLuint elapsedTimeUniform;
 
 void InitializeProgram()
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 	elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
 
 	GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
 	glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
 
 	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 03 OpenGLs Moving Triangle/tutorials.lua

 
-SetupProject("Tut 03 CPU Position Offset", "cpuPositionOffset.cpp")
-SetupProject("Tut 03 Shader Position Offset", "vertPositionOffset.cpp")
-SetupProject("Tut 03 Shader Calc Offset", "vertCalcOffset.cpp")
-SetupProject("Tut 03 Fragment Change Color", "fragChangeColor.cpp")
+SetupProject("Tut 03 CPU Position Offset", "cpuPositionOffset.cpp", "data/standard.vert", "data/standard.frag")
+SetupProject("Tut 03 Shader Position Offset", "vertPositionOffset.cpp", "data/positionOffset.vert", "data/standard.frag")
+SetupProject("Tut 03 Shader Calc Offset", "vertCalcOffset.cpp", "data/calcOffset.vert", "data/standard.frag")
+SetupProject("Tut 03 Fragment Change Color", "fragChangeColor.cpp", "data/calcOffset.vert", "data/calcColor.frag")

Tut 03 OpenGLs Moving Triangle/vertCalcOffset.cpp

 #include "../framework/framework.h"
 
 GLuint theProgram;
-GLuint positionAttrib;
 GLuint elapsedTimeUniform;
 
 void InitializeProgram()
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 	elapsedTimeUniform = glGetUniformLocation(theProgram, "time");
 
 	GLuint loopDurationUnf = glGetUniformLocation(theProgram, "loopDuration");
 	glUniform1f(elapsedTimeUniform, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
 
 	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 03 OpenGLs Moving Triangle/vertPositionOffset.cpp

 #include "../framework/framework.h"
 
 GLuint theProgram;
-GLuint positionAttrib;
 GLuint offsetLocation;
 
 void InitializeProgram()
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
 	offsetLocation = glGetUniformLocation(theProgram, "offset");
 }
 
 	glUniform2f(offsetLocation, fXOffset, fYOffset);
 
 	glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glEnableVertexAttribArray(0);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
 
 	glDrawArrays(GL_TRIANGLES, 0, 3);
 
-	glDisableVertexAttribArray(positionAttrib);
+	glDisableVertexAttribArray(0);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 04 Objects at Rest/AspectRatio.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorData = sizeof(vertexData) / 2;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
 
 	glDrawArrays(GL_TRIANGLES, 0, 36);
 
-	glDisableVertexAttribArray(positionAttrib);
-	glDisableVertexAttribArray(colorAttrib);
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 04 Objects at Rest/MatrixPerspective.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorData = sizeof(vertexData) / 2;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
 
 	glDrawArrays(GL_TRIANGLES, 0, 36);
 
-	glDisableVertexAttribArray(positionAttrib);
-	glDisableVertexAttribArray(colorAttrib);
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 04 Objects at Rest/OrthoCube.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 }
 
 
 	size_t colorData = sizeof(vertexData) / 2;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
 
 	glDrawArrays(GL_TRIANGLES, 0, 36);
 
-	glDisableVertexAttribArray(positionAttrib);
-	glDisableVertexAttribArray(colorAttrib);
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 04 Objects at Rest/ShaderPerspective.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	frustumScaleUnif = glGetUniformLocation(theProgram, "frustumScale");
 
 	size_t colorData = sizeof(vertexData) / 2;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData);
 
 	glDrawArrays(GL_TRIANGLES, 0, 36);
 
-	glDisableVertexAttribArray(positionAttrib);
-	glDisableVertexAttribArray(colorAttrib);
+	glDisableVertexAttribArray(0);
+	glDisableVertexAttribArray(1);
 	glUseProgram(0);
 
 	glutSwapBuffers();

Tut 04 Objects at Rest/data/ManualPerspective.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Tut 04 Objects at Rest/data/MatrixPerspective.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Tut 04 Objects at Rest/data/OrthoWithOffset.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Tut 04 Objects at Rest/data/StandardColors.frag

-#version 150
+#version 330
 
 smooth in vec4 theColor;
 

Tut 05 Objects in Depth/BaseVertexOverlap.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/DepthBuffer.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/DepthClamping.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/DepthFighting.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/OverlapNoDepth.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);
 	colorDataOffset += sizeof(float) * 4 * (numberOfVertices/2);
 
 	//Use the same buffer object previously bound to GL_ARRAY_BUFFER.
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, (void*)posDataOffset);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)posDataOffset);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/VertexClipping.cpp

 #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))
 
 GLuint theProgram;
-GLuint positionAttrib;
-GLuint colorAttrib;
 
 GLuint offsetUniform;
 GLuint perspectiveMatrixUnif;
 
 	theProgram = Framework::CreateProgram(shaderList);
 
-	positionAttrib = glGetAttribLocation(theProgram, "position");
-	colorAttrib = glGetAttribLocation(theProgram, "color");
-
 	offsetUniform = glGetUniformLocation(theProgram, "offset");
 
 	perspectiveMatrixUnif = glGetUniformLocation(theProgram, "perspectiveMatrix");
 
 	size_t colorDataOffset = sizeof(float) * 3 * numberOfVertices;
 	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
-	glEnableVertexAttribArray(positionAttrib);
-	glEnableVertexAttribArray(colorAttrib);
-	glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
-	glVertexAttribPointer(colorAttrib, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
+	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorDataOffset);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
 
 	glBindVertexArray(0);

Tut 05 Objects in Depth/data/Standard.frag

-#version 150
+#version 330
 
 smooth in vec4 theColor;
 

Tut 05 Objects in Depth/data/Standard.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

Tut 06 Objects in Motion/data/ColorPassthrough.frag

-#version 150
+#version 330
 
 smooth in vec4 theColor;
 

Tut 06 Objects in Motion/data/PosColorLocalTransform.vert

-#version 150
+#version 330
 
-in vec4 position;
-in vec4 color;
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
 
 smooth out vec4 theColor;
 

framework/framework.cpp

 	glutInitDisplayMode (GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL);
 	/* add command line argument "classic" for a pre-3.x context */
 	if ((argc != 2) || (strcmp (argv[1], "classic") != 0)) {
-		glutInitContextVersion (3, 2);
+		glutInitContextVersion (3, 3);
 		glutInitContextProfile(GLUT_CORE_PROFILE);
 	}
 	glutInitWindowSize (500, 500); 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.