| 190 |   |   p = glCreateProgram(); | 
                      
                        | 191 |   |   glAttachShader(p,f); | 
                      
                        | 192 |   |   glAttachShader(p,v); | 
                      
                        | 193 |   |   glLinkProgram(p); | 
                      
                        | 194 |   |   glUseProgram(p); | 
                      
                        | 195 |   | } | 
                      
                        | 196 |   |  | 
                      
                        | 197 |   |  | 
                      
                        | 198 |   | enum VAO_IDs { Triangles, NumVAOs }; | 
                      
                        | 199 |   | enum Buffer_IDs {ArrayBuffer,NumBuffers}; | 
                      
                        | 200 |   | enum Attrib_IDs { vPosition = 0 }; | 
                      
                        | 201 |   | GLuint VAOs[NumVAOs]; | 
                      
                        | 202 |   | GLuint Buffers[NumBuffers]; | 
                      
                        | 203 |   | #define NumVertices  6  | 
                      
                        | 204 |   |  | 
                      
                        | 205 |   | void init(void)  | 
                      
                        | 206 |   | { | 
                      
                        | 207 |   |   glGenVertexArrays(NumVAOs, VAOs); | 
                      
                        | 208 |   |   glBindVertexArray(VAOs[Triangles]); | 
                      
                        | 209 |   |   GLfloat vertices[NumVertices][2] = { | 
                      
                      
                        |   | 195 |   program = glCreateProgram(); | 
                      
                        |   | 196 |   glAttachShader(program, f); | 
                      
                        |   | 197 |   glAttachShader(program, v); | 
                      
                        |   | 198 |   glLinkProgram(program); | 
                      
                        |   | 199 |   glUseProgram(program); | 
                      
                        |   | 200 |  | 
                      
                        |   | 201 |   attribute_coord2d = glGetAttribLocation(program, "coord2d"); | 
                      
                        |   | 202 |   if (attribute_coord2d == -1) { | 
                      
                        |   | 203 |     fprintf(stderr, "Could not bind attribute coord2d\n"); | 
                      
                        |   | 204 |   } | 
                      
                        |   | 205 |   glEnableVertexAttribArray(attribute_coord2d); | 
                      
                        |   | 206 | } | 
                      
                        |   | 207 |  | 
                      
                        |   | 208 | void send_buffers_to_GPU(void) | 
                      
                        |   | 209 | { | 
                      
                        |   | 210 |   GLuint vertex_array_object; | 
                      
                        |   | 211 |   glGenVertexArrays(1, &vertex_array_object); | 
                      
                        |   | 212 |   glBindVertexArray(vertex_array_object); | 
                      
                        |   | 213 |    | 
                      
                        |   | 214 |   GLfloat vertices[][2] = { | 
                      
            
                      
                        | 228 |   |   glBindVertexArray(VAOs[Triangles]); | 
                      
                        | 229 |   |   glDrawArrays(GL_TRIANGLES, 0, NumVertices); | 
                      
                      
                        |   | 232 |   glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices); | 
                      
                        |   | 233 |   glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, NULL); | 
                      
                        |   | 234 |   glDrawArrays(GL_TRIANGLES, 0, 6); // Draw 6 vertices | 
                      
            
                      
                        | 254 |   |  1. To be able to continue and not get lost introduce shader compiler logs in case of compilation errors by adding the following code into {{{setShaders()}}} right at after vertex shader compilation: | 
                      
                        | 255 |   |    {{{ | 
                      
                        | 256 |   |    #!c | 
                      
                        | 257 |   |     GLint compiled; | 
                      
                        | 258 |   |     glGetShaderiv(v, GL_COMPILE_STATUS, &compiled ); | 
                      
                        | 259 |   |     if ( !compiled ) { | 
                      
                        | 260 |   |       GLsizei len; | 
                      
                        | 261 |   |       glGetShaderiv( v, GL_INFO_LOG_LENGTH, &len ); | 
                      
                        | 262 |   |       GLchar* log = malloc(sizeof(GLchar)*(len+1)); | 
                      
                        | 263 |   |       printf("Vertex Shader compilation failed: %s\n", log); | 
                      
                        | 264 |   |       free(log); | 
                      
                        | 265 |   |     } | 
                      
                        | 266 |   |    }}} | 
                      
                      
                        |   | 259 |  1. To be able to continue and not get lost introduce shader compiler logs in case of compilation errors by adding the following code into {{{create_shaders()}}} right at after vertex shader compilation: | 
                      
                        |   | 260 |   {{{ | 
                      
                        |   | 261 |   #!c | 
                      
                        |   | 262 |   GLint compiled; | 
                      
                        |   | 263 |   glGetShaderiv(v, GL_COMPILE_STATUS, &compiled ); | 
                      
                        |   | 264 |   if ( !compiled ) { | 
                      
                        |   | 265 |     GLsizei  maxLength, length; | 
                      
                        |   | 266 |     glGetShaderiv( v, GL_INFO_LOG_LENGTH, &maxLength ); | 
                      
                        |   | 267 |     GLchar* log = malloc(sizeof(GLchar)*(maxLength+1)); | 
                      
                        |   | 268 |     glGetShaderInfoLog(v,  maxLength, &length, log); | 
                      
                        |   | 269 |     printf("Vertex Shader compilation failed: %s\n", log); | 
                      
                        |   | 270 |     free(log); | 
                      
                        |   | 271 |   } | 
                      
                        |   | 272 |   }}} | 
                      
            
                      
                        | 269 |   |    {{{ | 
                      
                        | 270 |   |    #!c   | 
                      
                        | 271 |   |     GLint linked; | 
                      
                        | 272 |   |     glGetProgramiv(p, GL_LINK_STATUS, &linked ); | 
                      
                        | 273 |   |     if ( !linked ) { | 
                      
                        | 274 |   |       GLsizei len; | 
                      
                        | 275 |   |       glGetProgramiv( p, GL_INFO_LOG_LENGTH, &len ); | 
                      
                        | 276 |   |       GLchar* log = malloc(sizeof(GLchar)*(len+1)); | 
                      
                        | 277 |   |       glGetProgramInfoLog( p, len, &len, log ); | 
                      
                        | 278 |   |       printf("Shader linking failed: %s\n", log); | 
                      
                        | 279 |   |       free(log); | 
                      
                        | 280 |   |     } | 
                      
                        | 281 |   |    }}} | 
                      
                        | 282 |   |    Create some error to verify if it works. | 
                      
                      
                        |   | 275 |   {{{ | 
                      
                        |   | 276 |   #!c   | 
                      
                        |   | 277 |   GLint linked; | 
                      
                        |   | 278 |   glGetProgramiv(program, GL_LINK_STATUS, &linked ); | 
                      
                        |   | 279 |   if ( !linked ) { | 
                      
                        |   | 280 |     GLsizei len; | 
                      
                        |   | 281 |     glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len ); | 
                      
                        |   | 282 |     GLchar* log = malloc(sizeof(GLchar)*(len+1)); | 
                      
                        |   | 283 |     glGetProgramInfoLog(program, len, &len, log ); | 
                      
                        |   | 284 |     printf("Shader linking failed: %s\n", log); | 
                      
                        |   | 285 |     free(log); | 
                      
                        |   | 286 |   } | 
                      
                        |   | 287 |   }}} | 
                      
                        |   | 288 |   Create some error to verify if it works. | 
                      
            
                      
                        | 297 |   |                vertex_temperature, GL_STATIC_DRAW); | 
                      
                        | 298 |   |   glVertexAttribPointer(tPosition, 1, GL_FLOAT, GL_FALSE, 0, NULL); | 
                      
                        | 299 |   |   glEnableVertexAttribArray(tPosition);//toggle this | 
                      
                        | 300 |   |   }}} | 
                      
                        | 301 |   |   and adding corresponding IDs to `VAOs` and buffers. Replace shaders with | 
                      
                      
                        |   | 303 |              vertex_temperature, GL_STATIC_DRAW); | 
                      
                        |   | 304 |   }}} | 
                      
                        |   | 305 |   and adding corresponding global attribute and VBOs IDs at the top of `temperature.c` so that global section reads:    | 
                      
                        |   | 306 |   {{{ | 
                      
                        |   | 307 |   #!c | 
                      
                        |   | 308 |   GLuint program; | 
                      
                        |   | 309 |   GLuint vbo_vertices; | 
                      
                        |   | 310 |   GLUINT vbo_temperature; | 
                      
                        |   | 311 |   GLint attribute_coord2d; | 
                      
                        |   | 312 |   GLint attribute_temperature; | 
                      
                        |   | 313 |  }}}   | 
                      
                        |   | 314 |  Replace shaders with |