gvirtualxray Tutorial 01: Creating a Window and an OpenGL Context Using GLUT

Similar documents
OpenGL refresher. Advanced Computer Graphics 2012

Lecture 4 of 41. Lab 1a: OpenGL Basics

Information Coding / Computer Graphics, ISY, LiTH. OpenGL! ! where it fits!! what it contains!! how you work with it 11(40)

Introduction to Computer Graphics with OpenGL/GLUT

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 2: First Program

Precept 2 Aleksey Boyko February 18, 2011

Lecture 2 2D transformations Introduction to OpenGL

Computer Graphics. Bing-Yu Chen National Taiwan University

Comp 410/510 Computer Graphics Spring Programming with OpenGL Part 4: Three Dimensions

2/3/16. Interaction. Triangles (Clarification) Choice of Programming Language. Buffer Objects. The CPU-GPU bus. CSCI 420 Computer Graphics Lecture 3

OpenGL pipeline Evolution and OpenGL Shading Language (GLSL) Part 2/3 Vertex and Fragment Shaders

Interaction. CSCI 420 Computer Graphics Lecture 3

Computer Graphics (CS 4731) Lecture 11: Implementing Transformations. Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

ERKELEY DAVIS IRVINE LOS ANGELES RIVERSIDE SAN DIEGO SAN FRANCISCO EECS 104. Fundamentals of Computer Graphics. OpenGL

RECITATION - 1. Ceng477 Fall

// double buffering and RGB glutinitdisplaymode(glut_double GLUT_RGBA); // your own initializations

OpenGL/GLUT Intro. Week 1, Fri Jan 12

Computer graphics MN1

To Do. Computer Graphics (Fall 2008) Course Outline. Course Outline. Methodology for Lecture. Demo: Surreal (HW 3)

Computer Graphics (CS 4731) Lecture 11: Implementing Transformations. Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

CS 432 Interactive Computer Graphics

An Overview GLUT GLSL GLEW

Today s Agenda. Basic design of a graphics system. Introduction to OpenGL

Computer Graphics CS 543 Lecture 4 (Part 2) Building 3D Models (Part 2)

C OMPUTER G RAPHICS Thursday

VR-programming tools (procedural) More VRML later in this course! (declarative)

Books, OpenGL, GLUT, GLUI, CUDA, OpenCL, OpenCV, PointClouds, and G3D

Computer Graphics. OpenGL

CS 543 Lecture 1 (Part 3) Prof Emmanuel Agu. Computer Science Dept. Worcester Polytechnic Institute (WPI)

Announcement. Homework 1 has been posted in dropbox and course website. Due: 1:15 pm, Monday, September 12

Computer Graphics 1 Computer Graphics 1

API for creating a display window and using keyboard/mouse interations. See RayWindow.cpp to see how these are used for Assignment3

CS Computer Graphics: OpenGL, Continued

CS Computer Graphics: OpenGL, Continued

Computer graphics MN1

Lecture 3 Advanced Computer Graphics (CS & SE )

GL_COLOR_BUFFER_BIT, GL_PROJECTION, GL_MODELVIEW

Introduction to OpenGL

CS 548: COMPUTER GRAPHICS INTRODUCTION TO OPENGL AND GLUT SPRING 2015 DR. MICHAEL J. REALE

INTRODUCTION TO OPENGL PIPELINE

Computação Gráfica. Computer Graphics Engenharia Informática (11569) 3º ano, 2º semestre. Chap. 4 Windows and Viewports

Computer Graphics (CS 4731) OpenGL/GLUT(Part 1)

Introduction to Computer Graphics. Hardware Acceleration Review

An Interactive Introduction to OpenGL Programming

1 (Practice 1) Introduction to OpenGL

Books, OpenGL, GLUT, CUDA, OpenCL, OpenCV, PointClouds, G3D, and Qt

Computer Graphics (CS 543) Lecture 1 (Part 2): Introduction to OpenGL/GLUT (Part 1)

CS559: Computer Graphics. Lecture 12: OpenGL Li Zhang Spring 2008

CSE 167: Introduction to Computer Graphics Lecture #7: GLSL. Jürgen P. Schulze, Ph.D. University of California, San Diego Spring Quarter 2016

Graphics Programming. Computer Graphics, VT 2016 Lecture 2, Chapter 2. Fredrik Nysjö Centre for Image analysis Uppsala University

Building Models. CS 537 Interactive Computer Graphics Prof. David E. Breen Department of Computer Science

Erik Anchondo cse 520 lab 4

Exercise 1 Introduction to OpenGL

Interaction. CSCI 480 Computer Graphics Lecture 3

Teacher Assistant : Tamir Grossinger Reception hours: by - Building 37 / office -102 Assignments: 4 programing using

compatibility mode core mode

UNIT 7 LIGHTING AND SHADING. 1. Explain phong lighting model. Indicate the advantages and disadvantages. (Jun2012) 10M

CSC Graphics Programming. Budditha Hettige Department of Statistics and Computer Science

Ulf Assarsson Department of Computer Engineering Chalmers University of Technology

CS418 OpenGL & GLUT Programming Tutorial (I) Presented by : Wei-Wen Feng 1/30/2008

From system point of view, a graphics application handles the user input, changes the internal state, called the virtual world by modeling or

Installing and Running PyOpenGL (Windows)

Philip Calderon CSE 520 Lab 3 Color Shader

Interaction Computer Graphics I Lecture 3

Basic Graphics Programming

Lecture 5: Viewing. CSE Computer Graphics (Fall 2010)

Computer Graphics Course 2005

LECTURE 02 OPENGL API

Computer Graphics CS 543 Lecture 5 (Part 2) Implementing Transformations

Tutorial 04. Harshavardhan Kode. September 14, 2015

Modeling Transform. Chapter 4 Geometric Transformations. Overview. Instancing. Specify transformation for objects 李同益

CS475/CS675 - Computer Graphics. OpenGL Drawing

Programming using OpenGL: A first Introduction

CS 380 Introduction to Computer Graphics. LAB (1) : OpenGL Tutorial Reference : Foundations of 3D Computer Graphics, Steven J.

An Introduction to. Graphics Programming

CS 4204 Computer Graphics

Basic Graphics Programming

Lecture 2 CISC440/640 Spring Department of Computer and Information Science

11/1/13. Basic Graphics Programming. Teaching Assistant. What is OpenGL. Course Producer. Where is OpenGL used. Graphics library (API)

Computer Graphics (4731) Lecture 4: 2D Graphics Systems (Drawing Polylines, tiling, & Aspect Ratio)

Lecture 09: Shaders (Part 1)

Rendering. Part 1 An introduction to OpenGL

VTU EDUSAT PROGRAMME. Computer Graphics & Visualization

Introduction to OpenGL

2a. The triangles scale increases (expands) when the 'e' key is pressed and decreases (contracts) when the 'c' key is pressed.

Introduction to OpenGL

2 Transformations and Homogeneous Coordinates

CSC 470 Computer Graphics

OpenGL Transformations

COMP371 COMPUTER GRAPHICS

Hierarchical Modeling: Tree of Transformations, Display Lists and Functions, Matrix and Attribute Stacks,

Project Sketchpad. Ivan Sutherland (MIT 1963) established the basic interactive paradigm that characterizes interactive computer graphics:

CS559: Computer Graphics. Lecture 12: OpenGL Transformation Li Zhang Spring 2008

Lectures OpenGL Introduction

EECS 487: Interactive Computer Graphics

CS Computer Graphics: Intro to OpenGL

CS Computer Graphics: Intro to OpenGL

Introduction to OpenGL. CSCI 4229/5229 Computer Graphics Fall 2012

Cameras (and eye) Ideal Pinhole. Real Pinhole. Real + lens. Depth of field

12. Selection. - The objects selected are specified by hit records in the selection buffer. E.R. Bachmann & P.L. McDowell MV 4202 Page 1 of 13

Transcription:

gvirtualxray Tutorial 01: Creating a Window and an OpenGL Context Using GLUT Dr Franck P. Vidal 4 th September 2014 1

Contents Table of contents 2 List of figures 3 List of listings 3 1 Introduction 4 2 Header inclusion 5 3 Name Spaces 6 4 Global Variables 6 5 Function Declarations 7 6 Initialise GLUT 8 7 Initialise GLEW 9 8 Initialise OpenGL 9 9 Load 3D Objects 10 10 Display the 3D Scene 11 11 Idle Callback 13 12 Quit Callback 14 13 Frame Buffer Size Callback 14 14 Keyboard Callback 15 15 Scroll Button Callback 15 16 Next Tutorial... 16 A Program Source Code 16 Page 2 of 23

List of Figures 1 Screen capture of the tutorial.................................... 4 2 Topology of the first cube...................................... 10 3 Topology of the second cube.................................... 10 Listings 1 Header inclusion........................................... 5 2 Name spaces............................................. 6 3 Global variables........................................... 7 4 Function declarations........................................ 8 5 Initialise GLUT........................................... 8 6 Initialise GLEW........................................... 9 7 Initialise OpenGL.......................................... 9 8 Create 3D objects.......................................... 11 9 display the 3D scene......................................... 12 10 Idle callback............................................. 13 11 Quit callback............................................. 14 12 Change of frame buffer size callback................................ 14 13 Keyboard callback.......................................... 15 14 Scroll button callback........................................ 15 15 All the source code of this tutorial................................. 16 Page 3 of 23

1 Introduction The complete source code of this tutorial is available in Appendix A and on the Subversion (SVN) repository at example/src/tutorial_01_glut.cxx. It can be downloaded here: https://sourceforge.net/p/ gvirtualxray/code/head/tree/trunk/tutorials/src/tutorial_01_glut.cxx. It shows how to create a window with GLUT 1 and attach an OpenGL context to it. Two cubes are displayed (see Figure 1). They both rotate automatically. The rendering makes use of OpenGL Shading Language (GLSL) as Figure 1: Screen capture of the tutorial. the fix rendering pipeline and direct rendering are both depreciated in any modern computer graphics applications. It is an introductory tutorial, for more details, the reader may refer to the code (it is well documented) and the Doxygen 2 documentation of the project 3. The tutorial is organised as follows: Section 2 shows the header files to include. Section 3 shows some of the name spaces that can be included to lighten the code. Section 4 shows the global variables that are used. Section 5 what typical functions have to be declared in a basic GLUT program. Section 6 shows how to initialise GLUT. Section 7 shows how to initialise GLEW 4. Section 8 shows how to initialise OpenGL. How to load 3D objects is explained in Section 9 They are displayed in Section 10. Section 11 shows the idle callback. Section 12 shows the routine that is called when the program shuts. Section 13 shows what is done when the sze of the frame buffer changes, i.e. when the window is resized. Section 14 shows how to handle the keyboard. 1 http://www.pengl.org/resources/libraries/glut// 2 http://www.doxygen.org/ 3 http://gvirtualxray.sourceforge.net/documentation.php 4 http://glew.sourceforge.net/ Page 4 of 23

Section 15 shows how to handle the scroll button. Section 16 gives a preview of what the next tutorial will be about. Appendix A shows the source code of this tutorial. 2 Header inclusion Listing 1 shows the header files that need to be included to build a simple program based on the GLUT library: GL/glew.h is the GLEW header file. It can be found at http://glew.sourceforge.net/. GLEW is used to ensure that there is no undefined references when the Windows executable is created. glut.h is the GLUT header file. Be careful here as Apple installed it somewhere else... iostream is used for output streams. sstream is used to generate error messages exception is used for C++ exceptions. cstdlib defines return status (EXIT_SUCCESS and EXIT_FAILURE). gvirtualxray/types.h defines new types, e.g RATIONAL_NUMBER, VEC2, VEC3 and MATRIX4 to name a few. gvirtualxray/units.h defines units such as metre, kilometre, electronvolt, kiloelectron volt, gram, kilogram, etc. gvirtualxray/openglutilities.h defines some utility functions about OpenGL, e.g. matrix stacks, how to set the projection matrix, etc. gvirtualxray/polygonmesh.h corresponds to a class used to handle three-dimensional (3D) triangle meshes. gvirtualxray/shader.h corresponds to a class that handles (GLSL) programs. buildcube.h is used to create the triangle mesh of a cube. 1 // 2 // I n c l u d e 3 // 4 #i n c l u d e <GL/ glew. h> // Handle shaders 5 6 // Create an OpenGL context and attach a window to i t 7 #i f d e f APPLE 8 #i n c l u d e <GLUT/ g l u t. h> 9 #e l s e 10 #i n c l u d e <GL/ g l u t. h> 11 #e n d i f 12 13 #i n c l u d e <iostream > // Print e r r o r messages in the c o n s o l e 14 #i n c l u d e <sstream> // Generate e r r o r messages 15 #i n c l u d e <exception > // Catch C++ e x c e p t i o n 16 #i n c l u d e <c s t d l i b > // Define r e t u r n s t a t u s (EXIT_SUCCESS and EXIT_FAILURE) 17 18 // D e f i n e new types, e. g. ~RATIONAL_NUMBER, VEC2, VEC3 and MATRIX4 to name a few 19 #i n c l u d e " gvirtualxray /Types. h " 20 21 // Define u n i t s such as metre, kilometre, e l e c t r o n v o l t, gram, kilogram, e t c. 22 #i n c l u d e " gvirtualxray / Units. h " 23 24 // Some u t i l i t y f u n c t i o n s about OpenGL, e. g. matrix stacks, Page 5 of 23

25 // how to s e t the p r o j e c t i o n matrix, e t c. 26 #i n c l u d e " gvirtualxray / OpenGLUtilities. h " 27 28 #i n c l u d e " gvirtualxray /PolygonMesh. h " // Handle 3D t r i a n g l e meshes 29 #i n c l u d e " gvirtualxray / Shader. h " // Handle GLSL programs 30 31 #i n c l u d e " buildcube. h " // Create the t r i a n g l e mesh o f a cube Listing 1: Header inclusion. 3 Name Spaces Listing 2 shows the name spaces that can be selected: gvirtualxray includes graphics elements such as PolygonMesh and utilities such as Exception. std is used for output streams and exceptions. 1 // 2 // Name space 3 // 4 u s i n g namespace gvirtualxray ; 5 using namespace std ; Listing 2: Name spaces. 4 Global Variables Listing 3 shows the global variables that are used: GLsizei g_window_width keeps track of the window width. GLsizei g_window_height keeps track of the window height. int g_window_id is the GLUT window ID. Shader g_display_shader is the shader program used to display the 3D scene PolygonMesh g_polygon_mesh_1 is the polygon mesh of the first 3D object. PolygonMesh g_polygon_mesh_2 is the polygon mesh of the second 3D object. MATRIX4 g_object_1_rotation_matrix corresponds to the transformation matrix of the first 3D object. MATRIX4 g_object_2_rotation_matrixcorresponds to the transformation matrix of the second 3D object. vector<double> g_p_vertex_set_1 is an array containing the vertices of the first 3D object. vector<unsigned char> g_p_index_set_1 is an array containing vertex indices to build triangles from g_p_vertex_set_1. vector<float> g_p_vertex_set_2 is an array containing the vertices of the second 3D object. Note that no index is used in this case. RATIONAL_NUMBER g_zoom controls the zoom. const GLchar* g_vertex_shader is the source code of the vertex shader. const GLchar* g_fragment_shader is the source code of the fragment shader. Page 6 of 23

1 // 2 // Global v a r i a b l e s 3 // 4 // Keep t r a c k o f the window width 5 GLsizei g_window_width (640) ; 6 7 // Keep t r a c k o f the window h e i g h t 8 GLsizei g_window_height (480) ; 9 10 // GLUT window ID 11 i n t g_window_id ( 0 ) ; 12 13 // Shader program used to d i s p l a y the 3D scene 14 Shader g_ display_ shader ; 15 16 // 3D o b j e c t s as VAOs and VBOs 17 PolygonMesh g_polygon_mesh_1 ; 18 PolygonMesh g_polygon_mesh_2 ; 19 20 // Transformation m a t r i c e s 21 MATRIX4 g_ object_ 1_ rotation_ matrix ; 22 MATRIX4 g_ object_ 2_ rotation_ matrix ; 23 24 // Geometric data 25 vector <double> g_p_vertex_set_1 ; 26 v e c t o r <unsigned char> g_p_index_set_1 ; 27 vector <f l o a t > g_p_vertex_set_2 ; 28 29 // Control the zoom 30 RATIONAL_NUMBER g_zoom ( 5 0. 0 cm) ; 31 32 // Vertex s ha der 33 c o n s t GLchar g_vertex_shader = " \ 34 \n#v e r s i o n 110\n \ 35 \n \ 36 uniform mat4 g_ projection_ matrix ; \ n \ 37 uniform mat4 g_modelview_matrix ; \ n \ 38 \n \ 39 void main ( void ) \n \ 40 \n \ 41 g l _ P o s i t i o n = g_projection_matrix g_modelview_matrix vec4 ( gl_vertex. xyz, 1. 0 ) ; \ n \ 42 \n \ 43 " ; 44 45 // Fragment sh ad er 46 c o n s t GLchar g_fragment_shader = " \ 47 \n#v e r s i o n 110\n \ 48 \n \ 49 void main ( void ) \n \ 50 \n \ 51 gl_fragcolor = vec4 ( 1. 0, 1. 0, 1. 0, 1. 0 ) ; \ n \ 52 \n \ 53 " ; Listing 3: Global variables. 5 Function Declarations Listing 4 shows the typical functions that have to be declared in a basic GLUT program: initglut is used i) to initialise GLUT, ii) to create an OpenGL context, iii) to create a window, and iv) attach the OpenGL context to the window (see Section 6). initglew is used to initialise GLEW (see Section 7). Page 7 of 23

initgl is used to initialise some states of OpenGL, e.g. the background colour and enable the Z-buffer (see Section 8). load3dobjects loads the 3D geometry of two cubes (see Section 9). displaycallback render the two cubes on the screen (see Section 10). idlecallback is an idle callback (see Section 11). It is called once every event loop and can be used to perform animation. quitcallback is call when the program terminates (see Section 12). It closes the window and cleans up GLUT. framebuffersizecallback is called every time the frame buffer size changes (see Section 13). It initialises the viewport size and the projection matrix. keycallback is called every time a key is pressed or released on the keyboard (see Section 14). It can be used to close the window when the escape key is pressed. scrollcallback processes the mouse scroll button. It can be used to zoom in and out (see Section 15). 1 // 2 // Function d e c l a r a t i o n 3 // 4 void initglut ( i n t argc, char argv ) ; 5 void initglew ( ) ; 6 void initgl ( ) ; 7 void load3dobjects ( ) ; 8 void d i s p l a y C a l l b a c k ( ) ; 9 void i d l e C a l l b a c k ( ) ; 10 void q u i t C a l l b a c k ( ) ; 11 void f r a m e b u f f e r S i z e C a l l b a c k ( i n t awidth, i n t aheight ) ; 12 void keycallback ( unsigned char akey, i n t axposition, i n t ayposition ) ; 13 void s c r o l l C a l l b a c k ( i n t abutton, i n t astate, i n t axposition, i n t ayposition ) ; Listing 4: Function declarations. 6 Initialise GLUT Listing 5 shows how to initialise GLUT to create an OpenGL core profile 3.2 context and how to attach a window to it. There are nime main steps: Initialise the GLUT library. Create a windowed mode window and its OpenGL context If the window has not been created, an exception is thrown. Register GLUT callbacks 1 // 2 void initglut ( i n t argc, char argv ) 3 // 4 5 // GLUT i n i t i a l i s a t i o n 6 g l u t I n i t (&argc, argv ) ; 7 8 // Create a windowed mode window and i t s OpenGL context 9 glutinitwindowsize ( g_window_width, g_window_height ) ; 10 glutinitdisplaymode ( GLUT_RGB GLUT_DOUBLE GLUT_DEPTH) ; 11 g_window_id = glutcreatewindow ( " gvirtualxray T u t o r i a l 01 " ) ; 12 13 // The window has not been c r e a t e d Page 8 of 23

14 i f (! g_window_id ) 15 16 throw Exception ( FILE, FUNCTION, LINE, 17 "ERROR: cannot c r e a t e a GLUT windowed mode window and i t s OpenGL context. " ) ; 18 19 20 // R e g i s t e r GLUT c a l l b a c k s 21 glutdisplayfunc ( d i s p l a y C a l l b a c k ) ; 22 glutreshapefunc ( f r a m e b u f f e r S i z e C a l l b a c k ) ; 23 glutkeyboardfunc ( keycallback ) ; 24 glutmousefunc ( s c r o l l C a l l b a c k ) ; 25 g l u t I d l e F u n c ( i d l e C a l l b a c k ) ; 26 Listing 5: Initialise GLUT. 7 Initialise GLEW Listing 6 shows how to initialise GLEW. 1 // 2 void initglew ( ) 3 // 4 5 GLenum e r r = g l e w I n i t ( ) ; 6 i f (GLEW_OK!= e r r ) 7 8 std : : s t r i n g s t r e a m error_message ; 9 error_message << "ERROR: cannot i n i t i a l i s e GLEW: \ t " << glewgeterrorstring ( e r r ) ; 10 11 throw Exception ( FILE, FUNCTION, LINE, error_message. s t r ( ) ) ; 12 13 Listing 6: Initialise GLEW. 8 Initialise OpenGL Listing 7 shows how to initialise some OpenGL states (Z-buffer, and background colour) and check OpenGL s error status. 1 // 2 void initgl ( ) 3 // 4 5 // Enable the Z b u f f e r 6 glenable (GL_DEPTH_TEST) ; 7 8 // Set the background c o l o u r 9 g l C l e a r C o l o r ( 0. 5, 0. 5, 0. 5, 1. 0 ) ; 10 11 // Check i f any OpenGL e r r o r has occurred. 12 // I f any has, an e x c e p t i o n i s thrown 13 checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; 14 Listing 7: Initialise OpenGL. Page 9 of 23

9 Load 3D Objects Listing 8 shows how to create 3D objects. It implements two cubes. The first one makes use of a vertex list and an index list (see Figure 2). The second cube only makes use of a vertex list. Vertices are repeated several times. This is because each vertex is shared by different triangles. The second cube is therefore much bigger in term of memory usage. Listing 8 shows that our implementation supports both type of topology. 0 2 y 1 3 x 4 z 6 5 7 (a) Geometry. Vertex List Vertex ID x y z 0-2.5 cm 2.5 cm -2.5 cm 1-2.5 cm 2.5 cm 2.5 cm 2 2.5 cm 2.5 cm -2.5 cm 3 2.5 cm 2.5 cm 2.5 cm 4-2.5 cm -2.5 cm -2.5 cm 5-2.5 cm -2.5 cm 2.5 cm 6 2.5 cm -2.5 cm -2.5 cm 7 2.5 cm -2.5 cm 2.5 cm (b) Vertex list. Face List i j k Top face 1 2 0 Top face 2 1 3 Bottom face 6 5 4 Bottom face 5 6 7 Front face 5 3 1 Front face 3 5 7 Back face 2 4 0 Back face 4 2 6 Left face 5 0 4 Left face 0 5 1 Right face 2 7 6 Right face 7 2 3 (c) Index list. Figure 2: Topology of the first cube. 2, 20, 25, 27 1, 3, 18, 22, 30, 34 y 0, 4, 14, 29 5, 13, 15, 35 x 8, 19, 21, 26 z 6, 10, 23, 32 7, 9, 12, 16, 24, 28 11, 17, 31, 33 (a) Geometry. Vertex List Vertex ID x y z 0-2.5 cm 2.5 cm 2.5 cm 1 2.5 cm 2.5 cm -2.5 cm.... 34 2.5 cm 2.5 cm -2.5 cm 35 2.5 cm 2.5 cm 2.5 cm (b) Vertex list. Figure 3: Topology of the second cube. buildcube(length_1, cube_centre, g_p_vertex_set_1, g_p_index_set_1) creates the data required to model a cube using vertex data and index data. Its length is length_1 and it is centred on cube_centre (0, 0, 0). buildcube(length_2, cube_centre, g_p_vertex_set_2) creates the data of another cube, but using vertex data only. Its length is length_2 and it is also centred on cube_centre. g_polygon_mesh_1.setexternaldata(gl_triangles, &g_p_vertex_set_1, &g_p_index_set_1, true, GL_STATIC_DRAW) loads both the vertex (&g_p_vertex_set_1) and index (&g_p_index_set_1) data of the geometry. GL_TRIANGLES indicates that the mesh corresponds to a triangle mesh. true means that the vertex buffer object (VBO) should be created instantly if possible. GL_STATIC_DRAW is used because the (VBO) data will be set once and used many times. g_polygon_mesh_2.setexternaldata(gl_triangles, &g_p_vertex_set_2, true, GL_STATIC_DRAW) loads the vertex (&g_p_vertex_set_2) data of the geometry. There is no index data for this mesh. Page 10 of 23

1 // 2 void load3dobjects ( ) 3 // 4 5 // Centre o f the cubes 6 VEC3 cube_centre ( 0, 0, 0) ; 7 8 // S i z e o f the cubes 9 RATIONAL_NUMBER length_ 1 ( 5. 0 cm) ; 10 RATIONAL_NUMBER length_ 2 ( 1 0. 0 cm) ; 11 12 // Create the cube using v e r t e x data and index data 13 buildcube ( length_1, cube_ centre, g_p_vertex_set_1, g_p_index_set_1 ) ; 14 15 // Create the cube using v e r t e x data only 16 buildcube ( length_2, cube_ centre, g_p_vertex_set_2 ) ; 17 18 // Set geometry ( using VAOs and VBOs) 19 g_polygon_mesh_1. setexternaldata (GL_TRIANGLES, 20 &g_p_vertex_set_1, 21 &g_p_index_set_1, 22 true, 23 GL_STATIC_DRAW) ; 24 25 g_polygon_mesh_2. setexternaldata (GL_TRIANGLES, 26 &g_p_vertex_set_2, 27 true, 28 GL_STATIC_DRAW) ; 29 Listing 8: Create 3D objects. 10 Display the 3D Scene Listing 9 shows how to display the 3D objects. // Clear the buffers glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT) clears both the fragment and Z buffers. pushshaderprogram() adds the current shader program to the shader stack. It may become handy when multiple shaders are used. g_display_shader.enable() enables the given shader program. Its unique OpenGL ID can be retrieved with g_display_shader.getprogramhandle(). The status of the frame buffer object (FBO) can be checked with checkfboerrorstatus( FILE, FUNCTION, LINE ). If an error had occurred, then an exception will be thrown. The status of the OpenGL s error flag can be checked with checkopenglerrorstatus( FILE, FUNCTION, LINE ). If an error had occurred, then an exception will be thrown. g_current_projection_matrix is the current projection matrix. g_current_modelview_matrix is the current modelling-viewing matrix. Section 13 shows how it can be set. Using a shader program, when the fixed pipeline functions are disabled (as in modern OpenGL implementation), the programmer has to supply the projection and modelling-viewing matrices to the shader program. This is what Lines 22 to 30 are taking care of in Listing 9. To store the current transformation matrices, pushmodelviewmatrix() and pushprojectionmatrix() are used. They replace the old glmatrixmode and glpushmatrix, which are no longer available in modern OpenGL. Page 11 of 23

To translate the 1 st object, write g_current_modelview_matrix *= MATRIX4::buildTranslationMatrix(VEC3(8.0 * cm, 0.0, 0.0)). function gltranslate, which is now depreciated. This is similar to the old To rotate this object, write g_current_modelview_matrix *= g_object_1_rotation_matrix. This is similar to the old function glrotate, which is now depreciated. To apply the changes to the shader program, call applymodelviewmatrix(). The 1 st polygon mesh is displayed with g_polygon_mesh_1.display(). The transformation matrices are restored from the stack using popmodelviewmatrix() and popprojectionmatrix(). The transformation matrices are stored in the stack using pushmodelviewmatrix() and pushprojectionmatrix(). To translate the 2 nd object, write g_current_modelview_matrix *= MATRIX4::buildTranslationMatrix(VEC3(-8.0 * cm, 0.0, 0.0)). To rotate this object, write g_current_modelview_matrix *= g_object_2_rotation_matrix. To apply the changes to the shader program, call applymodelviewmatrix(). The 2 nd object is displayed by g_polygon_mesh_2.display(). The transformation matrices are restored from the stack using popmodelviewmatrix() and popprojectionmatrix(). popshaderprogram() disables the current shader and restores the previous shader from the stack. Finally, we check the error status of both OpenGL and the (FBO). 1 // 2 void d i s p l a y C a l l b a c k ( ) 3 // 4 5 // Clear the b u f f e r s 6 g l C l e a r (GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT) ; 7 8 // Add the c u r r e n t shader to the shader s t a c k 9 pushshaderprogram ( ) ; 10 11 // Enable the s ha der 12 g_display_shader. enable ( ) ; 13 GLint shader_ id ( g_ display_ shader. getprogramhandle ( ) ) ; 14 15 // Check the s t a t u s o f OpenGL and o f the c u r r e n t FBO 16 checkfboerrorstatus ( FILE, FUNCTION, LINE ) ; 17 checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; 18 19 // A handle f o r shader r e s o u r c e s 20 GLuint handle ( 0 ) ; 21 22 // Upload the p r o j e c t i o n matrix 23 handle = glgetuniformlocation ( shader_id, " g_ projection_ matrix " ) ; 24 gluniformmatrix4fv ( handle, 1, GL_FALSE, g_current_projection_matrix. get ( ) ) ; 25 checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; 26 27 // Upload the modelview matrix 28 handle = glgetuniformlocation ( shader_id, " g_modelview_matrix " ) ; 29 gluniformmatrix4fv ( handle, 1, GL_FALSE, g_current_modelview_matrix. get ( ) ) ; 30 checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; 31 32 // Store the c u r r e n t t r a n s f o r m a t i o n m a t r i c e s Page 12 of 23

33 pushmodelviewmatrix ( ) ; 34 pushprojectionmatrix ( ) ; 35 36 // T r a n s l a t e the 1 s t o b j e c t 37 g_current_modelview_matrix = MATRIX4 : : b u i l d T r a n s l a t i o n M a t r i x ( 38 VEC3( 8. 0 cm, 0. 0, 0. 0 ) ) ; 39 40 // Rotate the 1 s t o b j e c t 41 g_current_modelview_matrix = g_ object_ 1_ rotation_ matrix ; 42 43 // Apply the change to the s had er program 44 applymodelviewmatrix ( ) ; 45 46 // Display the 1 s t o b j e c t 47 g_polygon_mesh_1. d i s p l a y ( ) ; 48 49 // Restore the c u r r e n t t r a n s f o r m a t i o n matrix 50 popmodelviewmatrix ( ) ; 51 popprojectionmatrix ( ) ; 52 53 // Store the c u r r e n t t r a n s f o r m a t i o n m a t r i c e s 54 pushmodelviewmatrix ( ) ; 55 pushprojectionmatrix ( ) ; 56 57 // T r a n s l a t e the 2nd o b j e c t 58 g_current_modelview_matrix = MATRIX4 : : b u i l d T r a n s l a t i o n M a t r i x ( 59 VEC3( 8.0 cm, 0. 0, 0. 0 ) ) ; 60 61 // Rotate the 2nd o b j e c t 62 g_current_modelview_matrix = g_ object_ 2_ rotation_ matrix ; 63 64 // Apply the change to the s had er program 65 applymodelviewmatrix ( ) ; 66 67 // Display the 2nd o b j e c t 68 g_polygon_mesh_2. d i s p l a y ( ) ; 69 70 // Restore the c u r r e n t t r a n s f o r m a t i o n matrix 71 popmodelviewmatrix ( ) ; 72 popprojectionmatrix ( ) ; 73 74 // D i s a b l e the shader and r e s t o r e the p r e v i o u s shader from the s t a c k 75 popshaderprogram ( ) ; 76 77 // Check the s t a t u s o f OpenGL and o f the c u r r e n t FBO 78 checkfboerrorstatus ( FILE, FUNCTION, LINE ) ; 79 checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; 80 81 // Swap f r o n t and back b u f f e r s 82 glutswapbuffers ( ) ; 83 Listing 9: display the 3D scene. 11 Idle Callback In the idle callback the rotation matrices are updated to create an animation (see Listing 10). g_object_1_rotation_matrix.rotate(1.0, VEC3(1.0, 0.0, 0.0)) multiplies the transformation matrix (g_object_1_rotation_matrix) by a rotation matrix defined by angle in degrees (1.0 in this example) and a rotation axis (VEC3(1.0, 0.0, 0.0)). 1 // 2 void i d l e C a l l b a c k ( ) 3 // 4 Page 13 of 23

5 // Rotate the o b j e c t s 6 g_object_1_rotation_matrix. r o t a t e ( 1. 0, VEC3( 1. 0, 0. 0, 0. 0 ) ) ; 7 g_object_2_rotation_matrix. r o t a t e ( 2. 0, VEC3( 0. 0, 1. 0, 0. 0 ) ) ; 8 9 // Redisplay the scene 10 g l u t P o s t R e d i s p l a y ( ) ; 11 Listing 10: Idle callback. 12 Quit Callback Listing 11 shows how to clean up GLUT. If the window exists, then it is destroyed. Finally, the GLUT application is terminated. 1 // 2 void q u i t C a l l b a c k ( ) 3 // 4 5 // The window e x i s t s 6 i f ( g_window_id ) 7 8 // Close the window 9 glutdestroywindow ( g_window_id ) ; 10 g_window_id = 0 ; 11 12 Listing 11: Quit callback. 13 Frame Buffer Size Callback This callback is called when the size of the frame buffer changes, that is to say when the size of the window changes. In this function three main things are performed (see Listing 12). Set the OpenGL s viewport with glviewport. Set the projection matrix. In this example; we use loadperspectiveprojectionmatrix to set g_current_projection_matrix. It is similar to gluperspective, which is not available in modern OpenGL. Set the modelling-viewing transformation. In this example; we use loadlookatmodelviewmatrix to set g_current_modelview_matrix. It is similar to glulookat, which is not available in modern OpenGL. 1 // 2 void f r a m e b u f f e r S i z e C a l l b a c k ( i n t width, i n t h e i g h t ) 3 // 4 5 // Avoid a d i v i s i o n by z e r o 6 i f ( h e i g h t == 0) 7 8 // Prevent d i v i d e by 0 9 h e i g h t = 1 ; 10 11 12 i n t x ( 0 ), y ( 0 ), w( width ), h ( h e i g h t ) ; 13 14 // Store the width and h e i g h t o f the window 15 g_window_width = width ; 16 g_window_height = h e i g h t ; 17 Page 14 of 23

18 // Compute the a s p e c t r a t i o o f the s i z e o f the window 19 double s c reen_aspect_ratio ( double ( g_window_width ) / double ( g_window_height ) ) ; 20 21 // Update the viewport 22 glviewport ( x, y, w, h ) ; 23 24 // Set up the p r o j e c t i o n matrix ( g_current_projection_matrix ) 25 l o a d P e r s p e c t i v e P r o j e c t i o n M a t r i x ( 4 5. 0, screen_aspect_ratio, 0. 1 cm, 5000.0 cm) ; 26 27 // Set up the modelling v i e w i n g matrix ( g_current_modelview_matrix ) 28 loadlookatmodelviewmatrix ( 5 0. 0 cm, 5 0. 0 cm, g_zoom, 29 0. 0, 0. 0, 0. 0, 30 0. 0, 1. 0, 0. 0 ) ; 31 32 // Redisplay the scene 33 g l u t P o s t R e d i s p l a y ( ) ; 34 Listing 12: Change of frame buffer size callback. 14 Keyboard Callback Listing 13 shows a typical GLUT keyboard callback. Here the window is closed when the user presses Q or Esc. 1 // 2 void keycallback ( unsigned char akey, i n t axposition, i n t ayposition ) 3 // 4 5 switch ( akey ) 6 7 // Close the program 8 c a s e 2 7 : 9 c a s e q : 10 q u i t C a l l b a c k ( ) ; 11 e x i t (EXIT_SUCCESS) ; 12 break ; 13 14 d e f a u l t : 15 break ; 16 17 18 // Redisplay the scene 19 g l u t P o s t R e d i s p l a y ( ) ; 20 Listing 13: Keyboard callback. 15 Scroll Button Callback The zoom is updated with the mouse wheel (see Listing 14). To update the modelling-viewing matrix, the Frame Buffer Size Callback is called. 1 // 2 void s c r o l l C a l l b a c k ( i n t abutton, i n t astate, i n t axposition, i n t ayposition ) 3 // 4 5 // The button i s down 6 i f ( astate == GLUT_DOWN) 7 8 // This i s a wheel event 9 i f ( abutton == 3) 10 Page 15 of 23

11 // Change the zoom 12 g_zoom += 5 cm ; 13 14 // Update the p r o j e c t i o n matrix 15 f r a m e b u f f e r S i z e C a l l b a c k ( g_window_width, g_window_height ) ; 16 17 // This i s a wheel event 18 e l s e i f ( abutton == 4) 19 20 // Change the zoom 21 g_zoom = 5 cm ; 22 23 // Update the p r o j e c t i o n matrix 24 f r a m e b u f f e r S i z e C a l l b a c k ( g_window_width, g_window_height ) ; 25 26 27 28 // Redisplay the scene 29 g l u t P o s t R e d i s p l a y ( ) ; 30 Listing 14: Scroll button callback. 16 Next Tutorial... In the next tutorial: Load the shader from a file compressed using the Zlib 5 We will see how to create an efficient mouse control to turn the 3D scene. A Program Source Code / @ f i l e t u t o r i a l _ 0 1 _ g l u t. cxx @brief Creating a Window and an OpenGL 2. x Context Using GLUT. @version 1. 0 @date 17/ 08/ 2014 @author Dr Franck P. Vidal @section L i c e n s e BSD 3 Clause L i c e n s e. For d e t a i l s on use and r e d i s t r i b u t i o n p l e a s e r e f e r to http : / / opensource. org / l i c e n s e s /BSD 3 Clause @section Copyright ( c ) by Dr Franck P. Vidal ( f r a n c k. p. v i d a l @ f p v i d a l. net ), http : / /www. f p v i d a l. net /, Dec 2013, 2013, v e r s i o n 1. 0, BSD 3 Clause L i c e n s e / // // I n c l u d e // 5 http://www.zlib.net/ Page 16 of 23

#i n c l u d e <GL/ glew. h> // Handle shaders // Create an OpenGL context and attach a window to i t #i f d e f APPLE #i n c l u d e <GLUT/ g l u t. h> #e l s e #i n c l u d e <GL/ g l u t. h> #e n d i f #i n c l u d e <iostream > // Print e r r o r messages in the c o n s o l e #i n c l u d e <sstream> // Generate e r r o r messages #i n c l u d e <exception > // Catch C++ e x c e p t i o n #i n c l u d e <c s t d l i b > // Define r e t u r n s t a t u s (EXIT_SUCCESS and EXIT_FAILURE) // D e f i n e new types, e. g. ~RATIONAL_NUMBER, VEC2, VEC3 and MATRIX4 to name a few #i n c l u d e " gvirtualxray /Types. h " // Define u n i t s such as metre, kilometre, e l e c t r o n v o l t, gram, kilogram, e t c. #i n c l u d e " gvirtualxray / Units. h " // Some u t i l i t y f u n c t i o n s about OpenGL, e. g. matrix stacks, // how to s e t the p r o j e c t i o n matrix, e t c. #i n c l u d e " gvirtualxray / OpenGLUtilities. h " #i n c l u d e " gvirtualxray /PolygonMesh. h " // Handle 3D t r i a n g l e meshes #i n c l u d e " gvirtualxray / Shader. h " // Handle GLSL programs #i n c l u d e " buildcube. h " // Create the t r i a n g l e mesh o f a cube // // Name space // u s i n g namespace gvirtualxray ; using namespace std ; // // Global v a r i a b l e s // // Keep t r a c k o f the window width GLsizei g_window_width (640) ; // Keep t r a c k o f the window h e i g h t GLsizei g_window_height (480) ; // GLUT window ID i n t g_window_id ( 0 ) ; // Shader program used to d i s p l a y the 3D scene Shader g_ display_ shader ; // 3D o b j e c t s as VAOs and VBOs PolygonMesh g_polygon_mesh_1 ; PolygonMesh g_polygon_mesh_2 ; // Transformation m a t r i c e s MATRIX4 g_ object_ 1_ rotation_ matrix ; MATRIX4 g_ object_ 2_ rotation_ matrix ; // Geometric data vector <double> g_p_vertex_set_1 ; v e c t o r <unsigned char> g_p_index_set_1 ; vector <f l o a t > g_p_vertex_set_2 ; // Control the zoom RATIONAL_NUMBER g_zoom ( 5 0. 0 cm) ; Page 17 of 23

// Vertex shader const GLchar g_vertex_shader = " \ \n#v e r s i o n 110\n \ \n \ uniform mat4 g_ projection_ matrix ; \ n \ uniform mat4 g_modelview_matrix ; \ n \ \n \ void main ( void ) \n \ \n \ g l _ P o s i t i o n = g_projection_matrix g_modelview_matrix vec4 ( gl_vertex. xyz, 1. 0 ) ; \ n \ \n \ " ; // Fragment sh ad er c o n s t GLchar g_fragment_shader = " \ \n#v e r s i o n 110\n \ \n \ void main ( void ) \n \ \n \ gl_fragcolor = vec4 ( 1. 0, 1. 0, 1. 0, 1. 0 ) ; \ n \ \n \ " ; // // Function d e c l a r a t i o n // void initglut ( i n t argc, char argv ) ; void initglew ( ) ; void initgl ( ) ; void load3dobjects ( ) ; void d i s p l a y C a l l b a c k ( ) ; void i d l e C a l l b a c k ( ) ; void q u i t C a l l b a c k ( ) ; void f r a m e b u f f e r S i z e C a l l b a c k ( i n t awidth, i n t aheight ) ; void keycallback ( unsigned char akey, i n t axposition, i n t ayposition ) ; void s c r o l l C a l l b a c k ( i n t abutton, i n t astate, i n t axposition, i n t ayposition ) ; // i n t main ( i n t argc, char argv ) // // Return code i n t return_ code (EXIT_SUCCESS) ; // R e g i s t e r the e x i t c a l l b a c k a t e x i t ( q u i t C a l l b a c k ) ; t r y // I n i t i a l i s e GLUT initglut ( argc, argv ) ; // I n i t i a l i s e GLEW initglew ( ) ; // I n i t i a l i s e OpenGL initgl ( ) ; // Give a t e x t ID to the v e r t e x and fragment shaders, i t can be u s e f u l when debuging shaders g_display_shader. s e t L a b e l s ( " g_vertex_shader ", " g_fragment_shader " ) ; // Load the s o u r c e code o f the shaders onto the GPU g_display_shader. loadsource ( g_vertex_shader, g_fragment_shader ) ; // I n i t i a l i s e the geometry o f the 3D o b j e c t s Page 18 of 23

load3dobjects ( ) ; // Set the p r o j e c t i o n matrix f r a m e b u f f e r S i z e C a l l b a c k ( g_window_width, g_window_height ) ; // Launch the event loop glutmainloop ( ) ; // Catch e x c e p t i o n i f any catch ( const e x c e p t i o n& e r r o r ) c e r r << e r r o r. what ( ) << endl ; return_ code = EXIT_FAILURE; // Close the window and shut GLFW i f needed q u i t C a l l b a c k ( ) ; // Return an e x i t code r e t u r n ( return_code ) ; // void initglut ( i n t argc, char argv ) // // GLUT i n i t i a l i s a t i o n g l u t I n i t (&argc, argv ) ; // Create a windowed mode window and i t s OpenGL context glutinitwindowsize ( g_window_width, g_window_height ) ; glutinitdisplaymode ( GLUT_RGB GLUT_DOUBLE GLUT_DEPTH) ; g_window_id = glutcreatewindow ( " gvirtualxray T u t o r i a l 01 " ) ; // The window has not been c r e a t e d i f (! g_window_id ) ; throw Exception ( FILE, FUNCTION, LINE, "ERROR: cannot c r e a t e a GLUT windowed mode window and i t s OpenGL context. " ) // R e g i s t e r GLUT c a l l b a c k s glutdisplayfunc ( d i s p l a y C a l l b a c k ) ; glutreshapefunc ( f r a m e b u f f e r S i z e C a l l b a c k ) ; glutkeyboardfunc ( keycallback ) ; glutmousefunc ( s c r o l l C a l l b a c k ) ; g l u t I d l e F u n c ( i d l e C a l l b a c k ) ; // void initglew ( ) // GLenum e r r = g l e w I n i t ( ) ; i f (GLEW_OK!= e r r ) std : : s t r i n g s t r e a m error_message ; error_message << "ERROR: cannot i n i t i a l i s e GLEW: \ t " << glewgeterrorstring ( e r r ) ; throw Exception ( FILE, FUNCTION, LINE, error_message. s t r ( ) ) ; // Page 19 of 23

void initgl ( ) // // Enable the Z b u f f e r glenable (GL_DEPTH_TEST) ; // Set the background c o l o u r g l C l e a r C o l o r ( 0. 5, 0. 5, 0. 5, 1. 0 ) ; // Check i f any OpenGL e r r o r has occurred. // I f any has, an e x c e p t i o n i s thrown checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; // void load3dobjects ( ) // // Centre o f the cubes VEC3 cube_centre ( 0, 0, 0) ; // S i z e o f the cubes RATIONAL_NUMBER length_ 1 ( 5. 0 cm) ; RATIONAL_NUMBER length_ 2 ( 1 0. 0 cm) ; // Create the cube using v e r t e x data and index data buildcube ( length_1, cube_ centre, g_p_vertex_set_1, g_p_index_set_1 ) ; // Create the cube using v e r t e x data only buildcube ( length_2, cube_ centre, g_p_vertex_set_2 ) ; // Set geometry ( using VAOs and VBOs) g_polygon_mesh_1. setexternaldata (GL_TRIANGLES, &g_p_vertex_set_1, &g_p_index_set_1, true, GL_STATIC_DRAW) ; g_polygon_mesh_2. setexternaldata (GL_TRIANGLES, &g_p_vertex_set_2, true, GL_STATIC_DRAW) ; // void d i s p l a y C a l l b a c k ( ) // // Clear the b u f f e r s g l C l e a r (GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT) ; // Add the c u r r e n t shader to the shader s t a c k pushshaderprogram ( ) ; // Enable the s ha der g_display_shader. enable ( ) ; GLint shader_ id ( g_ display_ shader. getprogramhandle ( ) ) ; // Check the s t a t u s o f OpenGL and o f the c u r r e n t FBO checkfboerrorstatus ( FILE, FUNCTION, LINE ) ; checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; // A handle f o r shader r e s o u r c e s GLuint handle ( 0 ) ; // Upload the p r o j e c t i o n matrix Page 20 of 23

handle = glgetuniformlocation ( shader_id, " g_ projection_ matrix " ) ; gluniformmatrix4fv ( handle, 1, GL_FALSE, g_current_projection_matrix. get ( ) ) ; checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; // Upload the modelview matrix handle = glgetuniformlocation ( shader_id, " g_modelview_matrix " ) ; gluniformmatrix4fv ( handle, 1, GL_FALSE, g_current_modelview_matrix. get ( ) ) ; checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; // Store the c u r r e n t t r a n s f o r m a t i o n m a t r i c e s pushmodelviewmatrix ( ) ; pushprojectionmatrix ( ) ; // T r a n s l a t e the 1 s t o b j e c t g_current_modelview_matrix = MATRIX4 : : b u i l d T r a n s l a t i o n M a t r i x ( VEC3( 8. 0 cm, 0. 0, 0. 0 ) ) ; // Rotate the 1 s t o b j e c t g_current_modelview_matrix = g_ object_ 1_ rotation_ matrix ; // Apply the change to the s had er program applymodelviewmatrix ( ) ; // Display the 1 s t o b j e c t g_polygon_mesh_1. d i s p l a y ( ) ; // Restore the c u r r e n t t r a n s f o r m a t i o n matrix popmodelviewmatrix ( ) ; popprojectionmatrix ( ) ; // Store the c u r r e n t t r a n s f o r m a t i o n m a t r i c e s pushmodelviewmatrix ( ) ; pushprojectionmatrix ( ) ; // T r a n s l a t e the 2nd o b j e c t g_current_modelview_matrix = MATRIX4 : : b u i l d T r a n s l a t i o n M a t r i x ( VEC3( 8.0 cm, 0. 0, 0. 0 ) ) ; // Rotate the 2nd o b j e c t g_current_modelview_matrix = g_ object_ 2_ rotation_ matrix ; // Apply the change to the s had er program applymodelviewmatrix ( ) ; // Display the 2nd o b j e c t g_polygon_mesh_2. d i s p l a y ( ) ; // Restore the c u r r e n t t r a n s f o r m a t i o n matrix popmodelviewmatrix ( ) ; popprojectionmatrix ( ) ; // D i s a b l e the shader and r e s t o r e the p r e v i o u s shader from the s t a c k popshaderprogram ( ) ; // Check the s t a t u s o f OpenGL and o f the c u r r e n t FBO checkfboerrorstatus ( FILE, FUNCTION, LINE ) ; checkopenglerrorstatus ( FILE, FUNCTION, LINE ) ; // Swap f r o n t and back b u f f e r s glutswapbuffers ( ) ; // void i d l e C a l l b a c k ( ) // // Rotate the o b j e c t s Page 21 of 23

g_object_1_rotation_matrix. r o t a t e ( 1. 0, VEC3( 1. 0, 0. 0, 0. 0 ) ) ; g_object_2_rotation_matrix. r o t a t e ( 2. 0, VEC3( 0. 0, 1. 0, 0. 0 ) ) ; // Redisplay the scene g l u t P o s t R e d i s p l a y ( ) ; // void q u i t C a l l b a c k ( ) // // The window e x i s t s i f ( g_window_id ) // Close the window glutdestroywindow ( g_window_id ) ; g_window_id = 0 ; // void f r a m e b u f f e r S i z e C a l l b a c k ( i n t width, i n t h e i g h t ) // // Avoid a d i v i s i o n by z e r o i f ( h e i g h t == 0) // Prevent d i v i d e by 0 h e i g h t = 1 ; i n t x ( 0 ), y ( 0 ), w( width ), h ( h e i g h t ) ; // Store the width and h e i g h t o f the window g_window_width = width ; g_window_height = h e i g h t ; // Compute the a s p e c t r a t i o o f the s i z e o f the window double s c r e e n _ a s p e c t _ r a t i o ( double ( g_window_width ) / double ( g_window_height ) ) ; // Update the viewport glviewport ( x, y, w, h ) ; // Set up the p r o j e c t i o n matrix ( g_current_projection_matrix ) l o a d P e r s p e c t i v e P r o j e c t i o n M a t r i x ( 4 5. 0, screen_aspect_ratio, 0. 1 cm, 5000.0 cm) ; // Set up the modelling v i e w i n g matrix ( g_current_modelview_matrix ) loadlookatmodelviewmatrix ( 5 0. 0 cm, 5 0. 0 cm, g_zoom, 0. 0, 0. 0, 0. 0, 0. 0, 1. 0, 0. 0 ) ; // Redisplay the scene g l u t P o s t R e d i s p l a y ( ) ; // void keycallback ( unsigned char akey, i n t axposition, i n t ayposition ) // switch ( akey ) // Close the program c a s e 2 7 : c a s e q : q u i t C a l l b a c k ( ) ; Page 22 of 23

e x i t (EXIT_SUCCESS) ; break ; d e f a u l t : break ; // Redisplay the scene g l u t P o s t R e d i s p l a y ( ) ; // void s c r o l l C a l l b a c k ( i n t abutton, i n t astate, i n t axposition, i n t ayposition ) // // The button i s down i f ( astate == GLUT_DOWN) // This i s a wheel event i f ( abutton == 3) // Change the zoom g_zoom += 5 cm ; // Update the p r o j e c t i o n matrix f r a m e b u f f e r S i z e C a l l b a c k ( g_window_width, g_window_height ) ; // This i s a wheel event e l s e i f ( abutton == 4) // Change the zoom g_zoom = 5 cm ; // Update the p r o j e c t i o n matrix f r a m e b u f f e r S i z e C a l l b a c k ( g_window_width, g_window_height ) ; // Redisplay the scene g l u t P o s t R e d i s p l a y ( ) ; Listing 15: All the source code of this tutorial. Page 23 of 23