diff --git a/exercise4/Aufgabenstellung.pdf b/exercise4/Aufgabenstellung.pdf
new file mode 100644
index 0000000..f114b92
Binary files /dev/null and b/exercise4/Aufgabenstellung.pdf differ
diff --git a/exercise4/Programmaufbau.pdf b/exercise4/Programmaufbau.pdf
new file mode 100644
index 0000000..c097c72
Binary files /dev/null and b/exercise4/Programmaufbau.pdf differ
diff --git a/exercise4/build/cmake/CMakeLists.txt b/exercise4/build/cmake/CMakeLists.txt
new file mode 100644
index 0000000..1f073c1
--- /dev/null
+++ b/exercise4/build/cmake/CMakeLists.txt
@@ -0,0 +1,51 @@
+cmake_minimum_required( VERSION 2.6 )
+
+project(exercise4)
+
+# Gebraucht werden OpenGL und GLUT
+find_package(OpenGL REQUIRED)
+find_package(GLUT REQUIRED)
+
+# Definition der Headerdateien
+set(HEADERS
+ ../../include/abstract_curve.h
+ ../../include/application.h
+ ../../include/bezier_curve.h
+ ../../include/bspline.h
+ ../../include/control_points_editor.h
+ ../../include/curve_renderer.h
+ ../../include/hermite_spline.h
+ ../../include/lagrange_curve.h
+ ../../include/tiny_vec.h
+)
+
+# Definition der Sourcedateien
+set(SOURCES
+ ../../src/application.cpp
+ ../../src/control_points_editor.cpp
+ ../../src/main.cpp
+ ../../src/abstract_curve.cpp
+ ../../src/bezier_curve.cpp
+ ../../src/bspline.cpp
+ ../../src/curve_renderer.cpp
+ ../../src/hermite_spline.cpp
+ ../../src/lagrange_curve.cpp
+)
+
+# Includeverzeichnisse setzen
+include_directories(
+ ../../include
+)
+
+
+# Support fuer C++-11 aktivieren
+set(CMAKE_CXX_FLAGS "-std=c++11")
+
+# Ziel hinzufuegen
+add_executable(exercise4
+ ${SOURCES}
+ ${HEADERS}
+)
+
+# Bibliotheken linken
+target_link_libraries(exercise4 ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
diff --git a/exercise4/build/vs2012/curves.sln b/exercise4/build/vs2012/curves.sln
new file mode 100644
index 0000000..3d89f9d
--- /dev/null
+++ b/exercise4/build/vs2012/curves.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curves", "curves.vcxproj", "{ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.ActiveCfg = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.Build.0 = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.ActiveCfg = Release|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/exercise4/build/vs2012/curves.vcxproj b/exercise4/build/vs2012/curves.vcxproj
new file mode 100644
index 0000000..ccf3823
--- /dev/null
+++ b/exercise4/build/vs2012/curves.vcxproj
@@ -0,0 +1,111 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}
+ curves
+
+
+
+ Application
+ Unicode
+ true
+ v110
+
+
+ Application
+ Unicode
+ v110
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+
+
+
+ Disabled
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;FREEGLUT_STATIC;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ false
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ true
+ MachineX86
+
+
+
+
+ MaxSpeed
+ true
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;FREEGLUT_STATIC;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+ Level3
+ ProgramDatabase
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ false
+ true
+ true
+ true
+ MachineX86
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercise4/build/vs2015/curves.sln b/exercise4/build/vs2015/curves.sln
new file mode 100644
index 0000000..debb1e7
--- /dev/null
+++ b/exercise4/build/vs2015/curves.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2015
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curves", "curves.vcxproj", "{ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.ActiveCfg = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.Build.0 = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.ActiveCfg = Release|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/exercise4/build/vs2015/curves.vcxproj b/exercise4/build/vs2015/curves.vcxproj
new file mode 100644
index 0000000..5006fb8
--- /dev/null
+++ b/exercise4/build/vs2015/curves.vcxproj
@@ -0,0 +1,121 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ 15.0
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}
+ curves
+ 8.1
+
+
+
+ Application
+ Unicode
+ true
+ v140
+
+
+ Application
+ Unicode
+ v140
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>15.0
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+
+
+
+ Disabled
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ false
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ true
+ MachineX86
+
+
+ xcopy /Y "..\..\dependencies\freeglut\lib\freeglut.dll" "$(SolutionDir)$(Configuration)"
+ Copy freeglut .dll to executable location
+
+
+
+
+ MaxSpeed
+ true
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+ Level3
+ ProgramDatabase
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ false
+ true
+ true
+ true
+ MachineX86
+
+
+ xcopy /Y "..\..\dependencies\freeglut\lib\freeglut.dll" "$(SolutionDir)$(Configuration)"
+ Copy freeglut .dll to executable location
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercise4/build/vs2017/curves.sln b/exercise4/build/vs2017/curves.sln
new file mode 100644
index 0000000..ef40413
--- /dev/null
+++ b/exercise4/build/vs2017/curves.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2017
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "curves", "curves.vcxproj", "{ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.ActiveCfg = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Debug|Win32.Build.0 = Debug|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.ActiveCfg = Release|Win32
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/exercise4/build/vs2017/curves.vcxproj b/exercise4/build/vs2017/curves.vcxproj
new file mode 100644
index 0000000..e66c6e4
--- /dev/null
+++ b/exercise4/build/vs2017/curves.vcxproj
@@ -0,0 +1,121 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ 15.0
+ {ED74E400-FCC9-4F7A-AFD7-90A2C5300D90}
+ curves
+ 10.0.17134.0
+
+
+
+ Application
+ Unicode
+ true
+ v141
+
+
+ Application
+ Unicode
+ v141
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>15.0
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+
+
+
+ Disabled
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebug
+ Level3
+ EditAndContinue
+
+
+ false
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ true
+ MachineX86
+
+
+ xcopy /Y "..\..\dependencies\freeglut\lib\freeglut.dll" "$(SolutionDir)$(Configuration)"
+ Copy freeglut .dll to executable location
+
+
+
+
+ MaxSpeed
+ true
+ ../../include;../../dependencies/freeglut/include;%(AdditionalIncludeDirectories)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+ Level3
+ ProgramDatabase
+
+
+ ../../dependencies/freeglut/lib;%(AdditionalLibraryDirectories)
+ false
+ true
+ true
+ true
+ MachineX86
+
+
+ xcopy /Y "..\..\dependencies\freeglut\lib\freeglut.dll" "$(SolutionDir)$(Configuration)"
+ Copy freeglut .dll to executable location
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exercise4/dependencies/freeglut/include/GL/freeglut.h b/exercise4/dependencies/freeglut/include/GL/freeglut.h
new file mode 100644
index 0000000..0e6f8c6
--- /dev/null
+++ b/exercise4/dependencies/freeglut/include/GL/freeglut.h
@@ -0,0 +1,22 @@
+#ifndef __FREEGLUT_H__
+#define __FREEGLUT_H__
+
+/*
+ * freeglut.h
+ *
+ * The freeglut library include file
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "freeglut_std.h"
+#include "freeglut_ext.h"
+
+/*** END OF FILE ***/
+
+#endif /* __FREEGLUT_H__ */
diff --git a/exercise4/dependencies/freeglut/include/GL/freeglut_ext.h b/exercise4/dependencies/freeglut/include/GL/freeglut_ext.h
new file mode 100644
index 0000000..0c22c4f
--- /dev/null
+++ b/exercise4/dependencies/freeglut/include/GL/freeglut_ext.h
@@ -0,0 +1,271 @@
+#ifndef __FREEGLUT_EXT_H__
+#define __FREEGLUT_EXT_H__
+
+/*
+ * freeglut_ext.h
+ *
+ * The non-GLUT-compatible extensions to the freeglut library include file
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta,
+ * Creation date: Thu Dec 2 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ * Additional GLUT Key definitions for the Special key function
+ */
+#define GLUT_KEY_NUM_LOCK 0x006D
+#define GLUT_KEY_BEGIN 0x006E
+#define GLUT_KEY_DELETE 0x006F
+#define GLUT_KEY_SHIFT_L 0x0070
+#define GLUT_KEY_SHIFT_R 0x0071
+#define GLUT_KEY_CTRL_L 0x0072
+#define GLUT_KEY_CTRL_R 0x0073
+#define GLUT_KEY_ALT_L 0x0074
+#define GLUT_KEY_ALT_R 0x0075
+
+/*
+ * GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
+ */
+#define GLUT_ACTION_EXIT 0
+#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1
+#define GLUT_ACTION_CONTINUE_EXECUTION 2
+
+/*
+ * Create a new rendering context when the user opens a new window?
+ */
+#define GLUT_CREATE_NEW_CONTEXT 0
+#define GLUT_USE_CURRENT_CONTEXT 1
+
+/*
+ * Direct/Indirect rendering context options (has meaning only in Unix/X11)
+ */
+#define GLUT_FORCE_INDIRECT_CONTEXT 0
+#define GLUT_ALLOW_DIRECT_CONTEXT 1
+#define GLUT_TRY_DIRECT_CONTEXT 2
+#define GLUT_FORCE_DIRECT_CONTEXT 3
+
+/*
+ * GLUT API Extension macro definitions -- the glutGet parameters
+ */
+#define GLUT_INIT_STATE 0x007C
+
+#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
+
+#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
+#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB
+#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */
+
+#define GLUT_VERSION 0x01FC
+
+#define GLUT_RENDERING_CONTEXT 0x01FD
+#define GLUT_DIRECT_RENDERING 0x01FE
+
+#define GLUT_FULL_SCREEN 0x01FF
+
+#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204
+
+#define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205
+
+#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */
+
+/*
+ * New tokens for glutInitDisplayMode.
+ * Only one GLUT_AUXn bit may be used at a time.
+ * Value 0x0400 is defined in OpenGLUT.
+ */
+#define GLUT_AUX 0x1000
+
+#define GLUT_AUX1 0x1000
+#define GLUT_AUX2 0x2000
+#define GLUT_AUX3 0x4000
+#define GLUT_AUX4 0x8000
+
+/*
+ * Context-related flags, see fg_state.c
+ * Set the requested OpenGL version
+ */
+#define GLUT_INIT_MAJOR_VERSION 0x0200
+#define GLUT_INIT_MINOR_VERSION 0x0201
+#define GLUT_INIT_FLAGS 0x0202
+#define GLUT_INIT_PROFILE 0x0203
+
+/*
+ * Flags for glutInitContextFlags, see fg_init.c
+ */
+#define GLUT_DEBUG 0x0001
+#define GLUT_FORWARD_COMPATIBLE 0x0002
+
+
+/*
+ * Flags for glutInitContextProfile, see fg_init.c
+ */
+#define GLUT_CORE_PROFILE 0x0001
+#define GLUT_COMPATIBILITY_PROFILE 0x0002
+
+/*
+ * Process loop function, see fg_main.c
+ */
+FGAPI void FGAPIENTRY glutMainLoopEvent( void );
+FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
+FGAPI void FGAPIENTRY glutExit ( void );
+
+/*
+ * Window management functions, see fg_window.c
+ */
+FGAPI void FGAPIENTRY glutFullScreenToggle( void );
+FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
+
+/*
+ * Menu functions
+ */
+FGAPI void FGAPIENTRY glutSetMenuFont( int menuID, void* font );
+
+/*
+ * Window-specific callback functions, see fg_callbacks.c
+ */
+FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
+FGAPI void FGAPIENTRY glutPositionFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
+FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
+/* And also a destruction callback for menus */
+FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
+
+/*
+ * State setting and retrieval functions, see fg_state.c
+ */
+FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value );
+FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size);
+/* A.Donev: User-data manipulation */
+FGAPI void* FGAPIENTRY glutGetWindowData( void );
+FGAPI void FGAPIENTRY glutSetWindowData(void* data);
+FGAPI void* FGAPIENTRY glutGetMenuData( void );
+FGAPI void FGAPIENTRY glutSetMenuData(void* data);
+
+/*
+ * Font stuff, see fg_font.c
+ */
+FGAPI int FGAPIENTRY glutBitmapHeight( void* font );
+FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font );
+FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string );
+FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string );
+
+/*
+ * Geometry functions, see fg_geometry.c
+ */
+FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
+FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
+FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, double offset[3], double scale );
+FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, double offset[3], double scale );
+FGAPI void FGAPIENTRY glutWireCylinder( double radius, double height, GLint slices, GLint stacks);
+FGAPI void FGAPIENTRY glutSolidCylinder( double radius, double height, GLint slices, GLint stacks);
+
+/*
+ * Rest of functions for rendering Newell's teaset, found in fg_teapot.c
+ * NB: front facing polygons have clockwise winding, not counter clockwise
+ */
+FGAPI void FGAPIENTRY glutWireTeacup( double size );
+FGAPI void FGAPIENTRY glutSolidTeacup( double size );
+FGAPI void FGAPIENTRY glutWireTeaspoon( double size );
+FGAPI void FGAPIENTRY glutSolidTeaspoon( double size );
+
+/*
+ * Extension functions, see fg_ext.c
+ */
+typedef void (*GLUTproc)();
+FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
+
+/*
+ * Multi-touch/multi-pointer extensions
+ */
+
+#define GLUT_HAS_MULTI 1
+
+/* TODO: add device_id parameter,
+ cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */
+FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) );
+FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) );
+
+/*
+ * Joystick functions, see fg_joystick.c
+ */
+/* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */
+/* If you have a serious need for these functions in your application, please either
+ * contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net,
+ * switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's
+ * "js" library.
+ */
+int glutJoystickGetNumAxes( int ident );
+int glutJoystickGetNumButtons( int ident );
+int glutJoystickNotWorking( int ident );
+float glutJoystickGetDeadBand( int ident, int axis );
+void glutJoystickSetDeadBand( int ident, int axis, float db );
+float glutJoystickGetSaturation( int ident, int axis );
+void glutJoystickSetSaturation( int ident, int axis, float st );
+void glutJoystickSetMinRange( int ident, float *axes );
+void glutJoystickSetMaxRange( int ident, float *axes );
+void glutJoystickSetCenter( int ident, float *axes );
+void glutJoystickGetMinRange( int ident, float *axes );
+void glutJoystickGetMaxRange( int ident, float *axes );
+void glutJoystickGetCenter( int ident, float *axes );
+
+/*
+ * Initialization functions, see fg_init.c
+ */
+/* to get the typedef for va_list */
+#include
+FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion );
+FGAPI void FGAPIENTRY glutInitContextFlags( int flags );
+FGAPI void FGAPIENTRY glutInitContextProfile( int profile );
+FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, va_list ap ) );
+FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) );
+
+/* OpenGL >= 2.0 support */
+FGAPI void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib);
+FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib);
+FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2(GLint attrib);
+
+/* Mobile platforms lifecycle */
+FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)());
+FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
+/* state flags that can be passed to callback set by glutAppStatusFunc */
+#define GLUT_APPSTATUS_PAUSE 0x0001
+#define GLUT_APPSTATUS_RESUME 0x0002
+
+/*
+ * GLUT API macro definitions -- the display mode definitions
+ */
+#define GLUT_CAPTIONLESS 0x0400
+#define GLUT_BORDERLESS 0x0800
+#define GLUT_SRGB 0x1000
+
+#ifdef __cplusplus
+ }
+#endif
+
+/*** END OF FILE ***/
+
+#endif /* __FREEGLUT_EXT_H__ */
diff --git a/exercise4/dependencies/freeglut/include/GL/freeglut_std.h b/exercise4/dependencies/freeglut/include/GL/freeglut_std.h
new file mode 100644
index 0000000..a658c7c
--- /dev/null
+++ b/exercise4/dependencies/freeglut/include/GL/freeglut_std.h
@@ -0,0 +1,653 @@
+#ifndef __FREEGLUT_STD_H__
+#define __FREEGLUT_STD_H__
+
+/*
+ * freeglut_std.h
+ *
+ * The GLUT-compatible part of the freeglut library include file
+ *
+ * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+ * Written by Pawel W. Olszta,
+ * Creation date: Thu Dec 2 1999
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*
+ * Under windows, we have to differentiate between static and dynamic libraries
+ */
+#ifdef _WIN32
+/* #pragma may not be supported by some compilers.
+ * Discussion by FreeGLUT developers suggests that
+ * Visual C++ specific code involving pragmas may
+ * need to move to a separate header. 24th Dec 2003
+ */
+
+/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library
+ * pragmas or to 0 to exclude library pragmas.
+ * The default behavior depends on the compiler/platform.
+ */
+# ifndef FREEGLUT_LIB_PRAGMAS
+# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE)
+# define FREEGLUT_LIB_PRAGMAS 1
+# else
+# define FREEGLUT_LIB_PRAGMAS 0
+# endif
+# endif
+
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include
+
+/* Windows static library */
+# ifdef FREEGLUT_STATIC
+
+# define FGAPI
+# define FGAPIENTRY
+
+ /* Link with Win32 static freeglut lib */
+# if FREEGLUT_LIB_PRAGMAS
+# ifdef NDEBUG
+# pragma comment (lib, "freeglut_static.lib")
+# else
+# pragma comment (lib, "freeglut_staticd.lib")
+# endif
+# endif
+
+/* Windows shared library (DLL) */
+# else
+
+# define FGAPIENTRY __stdcall
+# if defined(FREEGLUT_EXPORTS)
+# define FGAPI __declspec(dllexport)
+# else
+# define FGAPI __declspec(dllimport)
+
+ /* Link with Win32 shared freeglut lib */
+# if FREEGLUT_LIB_PRAGMAS
+# ifdef NDEBUG
+# pragma comment (lib, "freeglut.lib")
+# else
+# pragma comment (lib, "freeglutd.lib")
+# endif
+# endif
+
+# endif
+
+# endif
+
+/* Drag in other Windows libraries as required by FreeGLUT */
+# if FREEGLUT_LIB_PRAGMAS
+# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */
+# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */
+# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */
+# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */
+# pragma comment (lib, "user32.lib") /* link Windows user lib */
+# endif
+
+#else
+
+/* Non-Windows definition of FGAPI and FGAPIENTRY */
+# define FGAPI
+# define FGAPIENTRY
+
+#endif
+
+/*
+ * The freeglut and GLUT API versions
+ */
+#define FREEGLUT 1
+#define GLUT_API_VERSION 4
+#define GLUT_XLIB_IMPLEMENTATION 13
+/* Deprecated:
+ cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */
+#define FREEGLUT_VERSION_2_0 1
+
+/*
+ * Always include OpenGL and GLU headers
+ */
+/* Note: FREEGLUT_GLES is only used to cleanly bootstrap headers
+ inclusion here; use GLES constants directly
+ (e.g. GL_ES_VERSION_2_0) for all other needs */
+#ifdef FREEGLUT_GLES
+# include
+# include
+# include
+#elif __APPLE__
+# include
+# include
+#else
+# include
+# include
+#endif
+
+/*
+ * GLUT API macro definitions -- the special key codes:
+ */
+#define GLUT_KEY_F1 0x0001
+#define GLUT_KEY_F2 0x0002
+#define GLUT_KEY_F3 0x0003
+#define GLUT_KEY_F4 0x0004
+#define GLUT_KEY_F5 0x0005
+#define GLUT_KEY_F6 0x0006
+#define GLUT_KEY_F7 0x0007
+#define GLUT_KEY_F8 0x0008
+#define GLUT_KEY_F9 0x0009
+#define GLUT_KEY_F10 0x000A
+#define GLUT_KEY_F11 0x000B
+#define GLUT_KEY_F12 0x000C
+#define GLUT_KEY_LEFT 0x0064
+#define GLUT_KEY_UP 0x0065
+#define GLUT_KEY_RIGHT 0x0066
+#define GLUT_KEY_DOWN 0x0067
+#define GLUT_KEY_PAGE_UP 0x0068
+#define GLUT_KEY_PAGE_DOWN 0x0069
+#define GLUT_KEY_HOME 0x006A
+#define GLUT_KEY_END 0x006B
+#define GLUT_KEY_INSERT 0x006C
+
+/*
+ * GLUT API macro definitions -- mouse state definitions
+ */
+#define GLUT_LEFT_BUTTON 0x0000
+#define GLUT_MIDDLE_BUTTON 0x0001
+#define GLUT_RIGHT_BUTTON 0x0002
+#define GLUT_DOWN 0x0000
+#define GLUT_UP 0x0001
+#define GLUT_LEFT 0x0000
+#define GLUT_ENTERED 0x0001
+
+/*
+ * GLUT API macro definitions -- the display mode definitions
+ */
+#define GLUT_RGB 0x0000
+#define GLUT_RGBA 0x0000
+#define GLUT_INDEX 0x0001
+#define GLUT_SINGLE 0x0000
+#define GLUT_DOUBLE 0x0002
+#define GLUT_ACCUM 0x0004
+#define GLUT_ALPHA 0x0008
+#define GLUT_DEPTH 0x0010
+#define GLUT_STENCIL 0x0020
+#define GLUT_MULTISAMPLE 0x0080
+#define GLUT_STEREO 0x0100
+#define GLUT_LUMINANCE 0x0200
+
+/*
+ * GLUT API macro definitions -- windows and menu related definitions
+ */
+#define GLUT_MENU_NOT_IN_USE 0x0000
+#define GLUT_MENU_IN_USE 0x0001
+#define GLUT_NOT_VISIBLE 0x0000
+#define GLUT_VISIBLE 0x0001
+#define GLUT_HIDDEN 0x0000
+#define GLUT_FULLY_RETAINED 0x0001
+#define GLUT_PARTIALLY_RETAINED 0x0002
+#define GLUT_FULLY_COVERED 0x0003
+
+/*
+ * GLUT API macro definitions -- fonts definitions
+ *
+ * Steve Baker suggested to make it binary compatible with GLUT:
+ */
+#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__)
+# define GLUT_STROKE_ROMAN ((void *)0x0000)
+# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001)
+# define GLUT_BITMAP_9_BY_15 ((void *)0x0002)
+# define GLUT_BITMAP_8_BY_13 ((void *)0x0003)
+# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004)
+# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005)
+# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006)
+# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007)
+# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008)
+#else
+ /*
+ * I don't really know if it's a good idea... But here it goes:
+ */
+ extern void* glutStrokeRoman;
+ extern void* glutStrokeMonoRoman;
+ extern void* glutBitmap9By15;
+ extern void* glutBitmap8By13;
+ extern void* glutBitmapTimesRoman10;
+ extern void* glutBitmapTimesRoman24;
+ extern void* glutBitmapHelvetica10;
+ extern void* glutBitmapHelvetica12;
+ extern void* glutBitmapHelvetica18;
+
+ /*
+ * Those pointers will be used by following definitions:
+ */
+# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman)
+# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman)
+# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15)
+# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
+# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10)
+# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24)
+# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10)
+# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12)
+# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18)
+#endif
+
+/*
+ * GLUT API macro definitions -- the glutGet parameters
+ */
+#define GLUT_WINDOW_X 0x0064
+#define GLUT_WINDOW_Y 0x0065
+#define GLUT_WINDOW_WIDTH 0x0066
+#define GLUT_WINDOW_HEIGHT 0x0067
+#define GLUT_WINDOW_BUFFER_SIZE 0x0068
+#define GLUT_WINDOW_STENCIL_SIZE 0x0069
+#define GLUT_WINDOW_DEPTH_SIZE 0x006A
+#define GLUT_WINDOW_RED_SIZE 0x006B
+#define GLUT_WINDOW_GREEN_SIZE 0x006C
+#define GLUT_WINDOW_BLUE_SIZE 0x006D
+#define GLUT_WINDOW_ALPHA_SIZE 0x006E
+#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F
+#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070
+#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071
+#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072
+#define GLUT_WINDOW_DOUBLEBUFFER 0x0073
+#define GLUT_WINDOW_RGBA 0x0074
+#define GLUT_WINDOW_PARENT 0x0075
+#define GLUT_WINDOW_NUM_CHILDREN 0x0076
+#define GLUT_WINDOW_COLORMAP_SIZE 0x0077
+#define GLUT_WINDOW_NUM_SAMPLES 0x0078
+#define GLUT_WINDOW_STEREO 0x0079
+#define GLUT_WINDOW_CURSOR 0x007A
+
+#define GLUT_SCREEN_WIDTH 0x00C8
+#define GLUT_SCREEN_HEIGHT 0x00C9
+#define GLUT_SCREEN_WIDTH_MM 0x00CA
+#define GLUT_SCREEN_HEIGHT_MM 0x00CB
+#define GLUT_MENU_NUM_ITEMS 0x012C
+#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190
+#define GLUT_INIT_WINDOW_X 0x01F4
+#define GLUT_INIT_WINDOW_Y 0x01F5
+#define GLUT_INIT_WINDOW_WIDTH 0x01F6
+#define GLUT_INIT_WINDOW_HEIGHT 0x01F7
+#define GLUT_INIT_DISPLAY_MODE 0x01F8
+#define GLUT_ELAPSED_TIME 0x02BC
+#define GLUT_WINDOW_FORMAT_ID 0x007B
+
+/*
+ * GLUT API macro definitions -- the glutDeviceGet parameters
+ */
+#define GLUT_HAS_KEYBOARD 0x0258
+#define GLUT_HAS_MOUSE 0x0259
+#define GLUT_HAS_SPACEBALL 0x025A
+#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B
+#define GLUT_HAS_TABLET 0x025C
+#define GLUT_NUM_MOUSE_BUTTONS 0x025D
+#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E
+#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F
+#define GLUT_NUM_DIALS 0x0260
+#define GLUT_NUM_TABLET_BUTTONS 0x0261
+#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262
+#define GLUT_DEVICE_KEY_REPEAT 0x0263
+#define GLUT_HAS_JOYSTICK 0x0264
+#define GLUT_OWNS_JOYSTICK 0x0265
+#define GLUT_JOYSTICK_BUTTONS 0x0266
+#define GLUT_JOYSTICK_AXES 0x0267
+#define GLUT_JOYSTICK_POLL_RATE 0x0268
+
+/*
+ * GLUT API macro definitions -- the glutLayerGet parameters
+ */
+#define GLUT_OVERLAY_POSSIBLE 0x0320
+#define GLUT_LAYER_IN_USE 0x0321
+#define GLUT_HAS_OVERLAY 0x0322
+#define GLUT_TRANSPARENT_INDEX 0x0323
+#define GLUT_NORMAL_DAMAGED 0x0324
+#define GLUT_OVERLAY_DAMAGED 0x0325
+
+/*
+ * GLUT API macro definitions -- the glutVideoResizeGet parameters
+ */
+#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384
+#define GLUT_VIDEO_RESIZE_IN_USE 0x0385
+#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386
+#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387
+#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388
+#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389
+#define GLUT_VIDEO_RESIZE_X 0x038A
+#define GLUT_VIDEO_RESIZE_Y 0x038B
+#define GLUT_VIDEO_RESIZE_WIDTH 0x038C
+#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D
+
+/*
+ * GLUT API macro definitions -- the glutUseLayer parameters
+ */
+#define GLUT_NORMAL 0x0000
+#define GLUT_OVERLAY 0x0001
+
+/*
+ * GLUT API macro definitions -- the glutGetModifiers parameters
+ */
+#define GLUT_ACTIVE_SHIFT 0x0001
+#define GLUT_ACTIVE_CTRL 0x0002
+#define GLUT_ACTIVE_ALT 0x0004
+
+/*
+ * GLUT API macro definitions -- the glutSetCursor parameters
+ */
+#define GLUT_CURSOR_RIGHT_ARROW 0x0000
+#define GLUT_CURSOR_LEFT_ARROW 0x0001
+#define GLUT_CURSOR_INFO 0x0002
+#define GLUT_CURSOR_DESTROY 0x0003
+#define GLUT_CURSOR_HELP 0x0004
+#define GLUT_CURSOR_CYCLE 0x0005
+#define GLUT_CURSOR_SPRAY 0x0006
+#define GLUT_CURSOR_WAIT 0x0007
+#define GLUT_CURSOR_TEXT 0x0008
+#define GLUT_CURSOR_CROSSHAIR 0x0009
+#define GLUT_CURSOR_UP_DOWN 0x000A
+#define GLUT_CURSOR_LEFT_RIGHT 0x000B
+#define GLUT_CURSOR_TOP_SIDE 0x000C
+#define GLUT_CURSOR_BOTTOM_SIDE 0x000D
+#define GLUT_CURSOR_LEFT_SIDE 0x000E
+#define GLUT_CURSOR_RIGHT_SIDE 0x000F
+#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010
+#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011
+#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012
+#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013
+#define GLUT_CURSOR_INHERIT 0x0064
+#define GLUT_CURSOR_NONE 0x0065
+#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066
+
+/*
+ * GLUT API macro definitions -- RGB color component specification definitions
+ */
+#define GLUT_RED 0x0000
+#define GLUT_GREEN 0x0001
+#define GLUT_BLUE 0x0002
+
+/*
+ * GLUT API macro definitions -- additional keyboard and joystick definitions
+ */
+#define GLUT_KEY_REPEAT_OFF 0x0000
+#define GLUT_KEY_REPEAT_ON 0x0001
+#define GLUT_KEY_REPEAT_DEFAULT 0x0002
+
+#define GLUT_JOYSTICK_BUTTON_A 0x0001
+#define GLUT_JOYSTICK_BUTTON_B 0x0002
+#define GLUT_JOYSTICK_BUTTON_C 0x0004
+#define GLUT_JOYSTICK_BUTTON_D 0x0008
+
+/*
+ * GLUT API macro definitions -- game mode definitions
+ */
+#define GLUT_GAME_MODE_ACTIVE 0x0000
+#define GLUT_GAME_MODE_POSSIBLE 0x0001
+#define GLUT_GAME_MODE_WIDTH 0x0002
+#define GLUT_GAME_MODE_HEIGHT 0x0003
+#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004
+#define GLUT_GAME_MODE_REFRESH_RATE 0x0005
+#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006
+
+/*
+ * Initialization functions, see fglut_init.c
+ */
+FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
+FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
+FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
+FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
+FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
+
+/*
+ * Process loop function, see fg_main.c
+ */
+FGAPI void FGAPIENTRY glutMainLoop( void );
+
+/*
+ * Window management functions, see fg_window.c
+ */
+FGAPI int FGAPIENTRY glutCreateWindow( const char* title );
+FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height );
+FGAPI void FGAPIENTRY glutDestroyWindow( int window );
+FGAPI void FGAPIENTRY glutSetWindow( int window );
+FGAPI int FGAPIENTRY glutGetWindow( void );
+FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title );
+FGAPI void FGAPIENTRY glutSetIconTitle( const char* title );
+FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height );
+FGAPI void FGAPIENTRY glutPositionWindow( int x, int y );
+FGAPI void FGAPIENTRY glutShowWindow( void );
+FGAPI void FGAPIENTRY glutHideWindow( void );
+FGAPI void FGAPIENTRY glutIconifyWindow( void );
+FGAPI void FGAPIENTRY glutPushWindow( void );
+FGAPI void FGAPIENTRY glutPopWindow( void );
+FGAPI void FGAPIENTRY glutFullScreen( void );
+
+/*
+ * Display-related functions, see fg_display.c
+ */
+FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
+FGAPI void FGAPIENTRY glutPostRedisplay( void );
+FGAPI void FGAPIENTRY glutSwapBuffers( void );
+
+/*
+ * Mouse cursor functions, see fg_cursor.c
+ */
+FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
+FGAPI void FGAPIENTRY glutSetCursor( int cursor );
+
+/*
+ * Overlay stuff, see fg_overlay.c
+ */
+FGAPI void FGAPIENTRY glutEstablishOverlay( void );
+FGAPI void FGAPIENTRY glutRemoveOverlay( void );
+FGAPI void FGAPIENTRY glutUseLayer( GLenum layer );
+FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void );
+FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window );
+FGAPI void FGAPIENTRY glutShowOverlay( void );
+FGAPI void FGAPIENTRY glutHideOverlay( void );
+
+/*
+ * Menu stuff, see fg_menu.c
+ */
+FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) );
+FGAPI void FGAPIENTRY glutDestroyMenu( int menu );
+FGAPI int FGAPIENTRY glutGetMenu( void );
+FGAPI void FGAPIENTRY glutSetMenu( int menu );
+FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value );
+FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu );
+FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value );
+FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value );
+FGAPI void FGAPIENTRY glutRemoveMenuItem( int item );
+FGAPI void FGAPIENTRY glutAttachMenu( int button );
+FGAPI void FGAPIENTRY glutDetachMenu( int button );
+
+/*
+ * Global callback functions, see fg_callbacks.c
+ */
+FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value );
+FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) );
+
+/*
+ * Window-specific callback functions, see fg_callbacks.c
+ */
+FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
+FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) );
+FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) );
+FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );
+FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) );
+
+FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) );
+FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval );
+FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) );
+FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) );
+FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) );
+
+FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) );
+FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) );
+FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) );
+
+/*
+ * State setting and retrieval functions, see fg_state.c
+ */
+FGAPI int FGAPIENTRY glutGet( GLenum query );
+FGAPI int FGAPIENTRY glutDeviceGet( GLenum query );
+FGAPI int FGAPIENTRY glutGetModifiers( void );
+FGAPI int FGAPIENTRY glutLayerGet( GLenum query );
+
+/*
+ * Font stuff, see fg_font.c
+ */
+FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character );
+FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character );
+FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character );
+FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character );
+FGAPI GLfloat FGAPIENTRY glutStrokeWidthf( void* font, int character ); /* GLUT 3.8 */
+FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
+FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
+FGAPI GLfloat FGAPIENTRY glutStrokeLengthf( void* font, const unsigned char *string ); /* GLUT 3.8 */
+
+/*
+ * Geometry functions, see fg_geometry.c
+ */
+
+FGAPI void FGAPIENTRY glutWireCube( double size );
+FGAPI void FGAPIENTRY glutSolidCube( double size );
+FGAPI void FGAPIENTRY glutWireSphere( double radius, GLint slices, GLint stacks );
+FGAPI void FGAPIENTRY glutSolidSphere( double radius, GLint slices, GLint stacks );
+FGAPI void FGAPIENTRY glutWireCone( double base, double height, GLint slices, GLint stacks );
+FGAPI void FGAPIENTRY glutSolidCone( double base, double height, GLint slices, GLint stacks );
+FGAPI void FGAPIENTRY glutWireTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
+FGAPI void FGAPIENTRY glutSolidTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
+FGAPI void FGAPIENTRY glutWireDodecahedron( void );
+FGAPI void FGAPIENTRY glutSolidDodecahedron( void );
+FGAPI void FGAPIENTRY glutWireOctahedron( void );
+FGAPI void FGAPIENTRY glutSolidOctahedron( void );
+FGAPI void FGAPIENTRY glutWireTetrahedron( void );
+FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
+FGAPI void FGAPIENTRY glutWireIcosahedron( void );
+FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
+
+/*
+ * Teapot rendering functions, found in fg_teapot.c
+ * NB: front facing polygons have clockwise winding, not counter clockwise
+ */
+FGAPI void FGAPIENTRY glutWireTeapot( double size );
+FGAPI void FGAPIENTRY glutSolidTeapot( double size );
+
+/*
+ * Game mode functions, see fg_gamemode.c
+ */
+FGAPI void FGAPIENTRY glutGameModeString( const char* string );
+FGAPI int FGAPIENTRY glutEnterGameMode( void );
+FGAPI void FGAPIENTRY glutLeaveGameMode( void );
+FGAPI int FGAPIENTRY glutGameModeGet( GLenum query );
+
+/*
+ * Video resize functions, see fg_videoresize.c
+ */
+FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query );
+FGAPI void FGAPIENTRY glutSetupVideoResizing( void );
+FGAPI void FGAPIENTRY glutStopVideoResizing( void );
+FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height );
+FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height );
+
+/*
+ * Colormap functions, see fg_misc.c
+ */
+FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue );
+FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component );
+FGAPI void FGAPIENTRY glutCopyColormap( int window );
+
+/*
+ * Misc keyboard and joystick functions, see fg_misc.c
+ */
+FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
+FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
+FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
+
+/*
+ * Misc functions, see fg_misc.c
+ */
+FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
+FGAPI void FGAPIENTRY glutReportErrors( void );
+
+/* Comment from glut.h of classic GLUT:
+
+ Win32 has an annoying issue where there are multiple C run-time
+ libraries (CRTs). If the executable is linked with a different CRT
+ from the GLUT DLL, the GLUT DLL will not share the same CRT static
+ data seen by the executable. In particular, atexit callbacks registered
+ in the executable will not be called if GLUT calls its (different)
+ exit routine). GLUT is typically built with the
+ "/MD" option (the CRT with multithreading DLL support), but the Visual
+ C++ linker default is "/ML" (the single threaded CRT).
+
+ One workaround to this issue is requiring users to always link with
+ the same CRT as GLUT is compiled with. That requires users supply a
+ non-standard option. GLUT 3.7 has its own built-in workaround where
+ the executable's "exit" function pointer is covertly passed to GLUT.
+ GLUT then calls the executable's exit function pointer to ensure that
+ any "atexit" calls registered by the application are called if GLUT
+ needs to exit.
+
+ Note that the __glut*WithExit routines should NEVER be called directly.
+ To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
+
+/* to get the prototype for exit() */
+#include
+
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
+FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
+FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
+FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
+#ifndef FREEGLUT_BUILDING_LIB
+#if defined(__GNUC__)
+#define FGUNUSED __attribute__((unused))
+#else
+#define FGUNUSED
+#endif
+static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
+#define glutInit glutInit_ATEXIT_HACK
+static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
+#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
+static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); }
+#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
+#endif
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+/*** END OF FILE ***/
+
+#endif /* __FREEGLUT_STD_H__ */
+
diff --git a/exercise4/dependencies/freeglut/include/GL/glut.h b/exercise4/dependencies/freeglut/include/GL/glut.h
new file mode 100644
index 0000000..6191f77
--- /dev/null
+++ b/exercise4/dependencies/freeglut/include/GL/glut.h
@@ -0,0 +1,21 @@
+#ifndef __GLUT_H__
+#define __GLUT_H__
+
+/*
+ * glut.h
+ *
+ * The freeglut library include file
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "freeglut_std.h"
+
+/*** END OF FILE ***/
+
+#endif /* __GLUT_H__ */
diff --git a/exercise4/dependencies/freeglut/lib/freeglut.dll b/exercise4/dependencies/freeglut/lib/freeglut.dll
new file mode 100644
index 0000000..c768c15
Binary files /dev/null and b/exercise4/dependencies/freeglut/lib/freeglut.dll differ
diff --git a/exercise4/dependencies/freeglut/lib/freeglut.lib b/exercise4/dependencies/freeglut/lib/freeglut.lib
new file mode 100644
index 0000000..498a576
Binary files /dev/null and b/exercise4/dependencies/freeglut/lib/freeglut.lib differ
diff --git a/exercise4/dependencies/freeglut/lib/freeglut_static.lib b/exercise4/dependencies/freeglut/lib/freeglut_static.lib
new file mode 100644
index 0000000..6e8a67c
Binary files /dev/null and b/exercise4/dependencies/freeglut/lib/freeglut_static.lib differ
diff --git a/exercise4/dependencies/freeglut/version.txt b/exercise4/dependencies/freeglut/version.txt
new file mode 100644
index 0000000..96751f3
--- /dev/null
+++ b/exercise4/dependencies/freeglut/version.txt
@@ -0,0 +1 @@
+freeglut-3.0.0
\ No newline at end of file
diff --git a/exercise4/include/abstract_curve.h b/exercise4/include/abstract_curve.h
new file mode 100644
index 0000000..738d9cd
--- /dev/null
+++ b/exercise4/include/abstract_curve.h
@@ -0,0 +1,76 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+Abstract curve.
+This class provides a basic interface for all curve types. It is
+constructed by passing a reference of a list of control points.
+It corresponds to the mathematical formulation of a curve c(t) via the
+"evaluate" method that returns a certain point as a function of the
+domain parameter "t". The range of "t" can be obtained with the methods
+"get_min_t" and "get_max_t".
+Since every point on a curve is generally the sum of the control
+points weightened with basis functions for every control point
+the interface declares the method "evaluate_basis" as a function
+of the parameter "t" and a control point. Specific curves have to
+implement that method accordingly.
+Because the control points are updated outside of an inherited instance
+of this class the method "control_points_updated" is called after
+every change, addition or removal of a control point.
+The rendering of the curve is not part of this interface but provided
+in another class called "curve_renderer".
+For debugging purpose an additional method called "set_text" is
+provided. Text put into the stream which is passed as a parameter to
+this function will be displayed in the main window.
+**************************************************************************/
+
+#pragma once
+
+// needed for arbitrary long lists
+#include
+// needed for the set_text method
+#include
+// needed for the data type "point2d"
+#include "tiny_vec.h"
+
+
+class abstract_curve
+{
+public:
+ // Initialize the curve and store a reference of the control points
+ abstract_curve(std::vector &control_points);
+
+ virtual ~abstract_curve();
+
+ // Get the minimum value of the domain
+ double get_min_t();
+ // Get the maximum value of the domain
+ double get_max_t();
+
+ // Evaluate a curve point as a function of the parameter "t". The
+ // range of that function is given by "get_min_t" and "get_max_t"
+ virtual point2d evaluate(double t);
+
+ // Evaluate a basis as a function of a control point and
+ // the parameter "t"
+ virtual double evaluate_basis(int point_num, double t) = 0;
+
+ // Shall be called whenever the control point set changes
+ virtual void control_points_updated();
+
+
+ // Get a constant list of control points
+ const std::vector& get_control_points() const;
+
+ // Put a text into the stream "stream" which will be displayed
+ // in the main window
+ virtual void set_text(std::stringstream &stream);
+
+protected:
+ // Range of the domain
+ double t_min, t_max;
+ // The reference of the control points
+ std::vector &control_points;
+};
\ No newline at end of file
diff --git a/exercise4/include/application.h b/exercise4/include/application.h
new file mode 100644
index 0000000..5c5c594
--- /dev/null
+++ b/exercise4/include/application.h
@@ -0,0 +1,139 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+The main program.
+This class provides the functionality of the main program. The program
+starts after calling the "run" method. This method initializes the GLUT
+system for rendering (using OpenGL) and user interaction. During the
+initialization process different methods are connected to certain events
+such as "display the window content", "act on mouse motion and buttons"
+or "act on key events". Furthermore the main context menu is initialized
+by calling the method "setup_context_menu".
+Whenever one of the events described above occurs the appropriate functions
+are called (They are however not called directly but via static functions
+that forward the event. Read the included PDF if you are interested why
+this is done and how it works).
+The instance of this class maintains an abstract curve that can be any
+of the implemented specific curve. Furthermore it maintains an instance of
+the "curve_renderer" and the graphical "control_points_editor".
+The rendering of the scene is done in the method "display" which configures
+OpenGL for orthographic projection and then renders the curve, the control
+points with the control polygon and the basis functions.
+The curve is changed in the method "context_menu_select" which is called
+whenever the user selects an option from the context menu. It is also used
+when a key is pressed.
+**************************************************************************/
+
+#pragma once
+
+
+// Needed for arbitrary long lists
+#include
+// Needed for openGL rendering and GLUT commands
+#include "GL/glut.h"
+// Needed for displaying text in the main window
+#include "GL/freeglut_ext.h"
+// Needed for the data type "point2d"
+#include "tiny_vec.h"
+
+#include "control_points_editor.h"
+#include "abstract_curve.h"
+#include "curve_renderer.h"
+
+
+// An enumeration of menu actions. Whenever something
+// from the context menu is selected the method "context_menu_select"
+// is invoked with an element of this enumeration as a parameter
+enum MenuActions
+{
+ MA_BEZIER_CURVE = 1, // show bezier curve
+ MA_LAGRANGE_CURVE, // show lagrange curve
+ MA_hermite_spline, // show hermite curve
+ MA_SHOW_BASIS, // show the basis functions
+ MA_BSPLINE, // show a bspline
+ MA_INCREASE_DEGREE, // increase degree of the spline
+ MA_DECREASE_DEGREE, // decrease degree of the spline
+ MA_DELETE_CTL_POINTS, // delete control points
+ MA_SHOW_GRID // show the dotted grid
+};
+
+
+
+
+class application
+{
+public:
+ // Initialize all non-GLUT related variables
+ application();
+
+ // Destroy allocated objects
+ ~application();
+
+ // Run the program using the command line arguments
+ int run(int argc, char* argv[]);
+
+private:
+ // The static instance of this program. Read the PDF for more details
+ static application *instance;
+
+ // The number of curve points to be evaluated for rendering the curve.
+ // Change it in the constructor for a different resolution
+ int curve_resolution;
+
+
+ // The control points editor
+ control_points_editor *ctl_editor;
+ // The list of control points
+ std::vector control_points;
+ // The curve to be evaluated
+ abstract_curve *curve;
+ // The renderer for the curve
+ curve_renderer *renderer;
+ // The degree of the spline
+ int spline_degree;
+ // Shall the basis functions be displayed?
+ bool show_basis_functions;
+ // Shall the grid be displayed?
+ bool show_grid;
+
+ bool menu_dirty;
+
+ // The event method on key presses
+ void key_down(unsigned char key, int x, int y);
+
+ // The event method on mouse button presses
+ void mouse_button(int button, int state);
+
+ // The event method on mouse motions
+ void mouse_move(int x, int y);
+
+ // The event method on context menu selections
+ void context_menu_select(int item);
+
+ // The event method on window content rendering
+ void display();
+
+ // Render a regular grid
+ void render_grid();
+
+ // Initialize the context menu
+ void setup_context_menu();
+
+ // Update the context menu
+ void update_context_menu();
+
+ // Set the curve type to the curve "c"
+ void set_curve_type(abstract_curve *c);
+
+ // Static callbacks...
+ static void key_down_callback(unsigned char key, int x, int y);
+ static void mouse_button_callback(int button, int state, int x, int y);
+ static void mouse_move_callback(int x, int y);
+ static void context_menu_callback(int item);
+ static void idle_callback();
+ static void display_callback();
+
+};
\ No newline at end of file
diff --git a/exercise4/include/bezier_curve.h b/exercise4/include/bezier_curve.h
new file mode 100644
index 0000000..61d7255
--- /dev/null
+++ b/exercise4/include/bezier_curve.h
@@ -0,0 +1,37 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+A Bezier curve.
+This class uses the interface "abstract_curve" to define a bezier curve.
+Read the information in "abstract_curve.h" for more details.
+*************************************************************************/
+
+#pragma once
+
+// provides the abstract curve interface
+#include "abstract_curve.h"
+
+
+
+class bezier_curve: public abstract_curve
+{
+public:
+ // Initialize the curve and store a reference of the control points
+ bezier_curve(std::vector& control_points);
+
+ // The specified "evaluate_basis" to evaluate a basis function for
+ // the control point "point_num" at the position "t"
+ double evaluate_basis(int point_num, double t);
+
+ // The specified "set_text" method to put arbitrary text into the
+ // stream "stream"
+ void set_text(std::stringstream &stream);
+
+
+private:
+ // A helper function to calculate "n choose k"
+ double binomial_coefficient(int n, int k);
+};
\ No newline at end of file
diff --git a/exercise4/include/bspline.h b/exercise4/include/bspline.h
new file mode 100644
index 0000000..84ee2f0
--- /dev/null
+++ b/exercise4/include/bspline.h
@@ -0,0 +1,51 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+A BSpline.
+This class uses the interface "abstract_curve" to define a bspline.
+Read the information in "abstract_curve.h" for more details.
+*************************************************************************/
+
+// provides the abstract curve interface
+#include "abstract_curve.h"
+
+
+class bspline: public abstract_curve
+{
+public:
+ // Initialize the curve and store a reference of the control points.
+ // Also the degree of the curve is provided through this constructor
+ bspline(std::vector& control_points, int degree);
+
+ // The specified "evaluate_basis" to evaluate a basis function for
+ // the control point "point_num" at the position "t"
+ double evaluate_basis(int point_num, double t);
+
+ // Another version of the evaluate_basis method with a specifyable
+ // degree. This method can be used for the recursive evaluation of
+ // the basis functions
+ double evaluate_basis(int degree, int point_num, double t);
+
+ // The specified "control_points_updated" to adjust the knot vector
+ // when control points are added or removed
+ void control_points_updated();
+
+
+ // The specified "set_text" method to put arbitrary text into the
+ // stream "stream"
+ void set_text(std::stringstream &stream);
+
+
+private:
+ // The degree of the spline
+ int degree;
+ // The knot vector (Knotenvektor)
+ std::vector u;
+
+ // Calculate the knot vector. This method is called from
+ // "control_points_updated"
+ void calculate_knot_vector();
+};
\ No newline at end of file
diff --git a/exercise4/include/control_points_editor.h b/exercise4/include/control_points_editor.h
new file mode 100644
index 0000000..a4419bf
--- /dev/null
+++ b/exercise4/include/control_points_editor.h
@@ -0,0 +1,71 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+The control points editor.
+This class provides a simple graphical editor for control points. It is
+constructed by passing a reference on a list of control points which is
+then changed according to mouse events. To recognize the events the user
+of an instance of this class has to call mouse_move when the mouse is
+moved and mouse_button when the mouse button states change. Because only
+a reference of the control points is used there is no method to return
+the control points as the original version which is in the hand of the
+user (of an object) is changed implicitly. To recognize whether a
+change occured the user can call "control_points_changed" which returns
+true in that case. To draw the control points a method called "draw"
+is implemented.
+**************************************************************************/
+
+#pragma once
+#include
+#include "tiny_vec.h"
+
+
+class control_points_editor
+{
+public:
+ // Initialize members and use a reference of "control_points"
+ // as point list to modify
+ control_points_editor(std::vector &control_points);
+
+ // Act on mouse moves. This method shall be called whenever
+ // the mouse was moved
+ void mouse_move(int x, int y);
+
+ // Act on mouse button events. This function shall be called
+ // whenever a button is pressed. The parameters "button" and "state"
+ // are to be filled with the corresponding GLUT states
+ void mouse_button(int button, int state);
+
+ // Return true when the control point list was changed.
+ bool control_points_changed();
+
+ // Draw the control points
+ void draw_control_points();
+
+ // Draw the control polygon
+ void draw_control_polygon();
+
+
+private:
+ // A reference on the control points
+ std::vector &control_points;
+ // The last recognized mouse position
+ int last_x, last_y;
+ // The currently selected point for moving
+ int selected_point;
+ // A hovered point
+ int hovered_point;
+ // True if the list of points was changed
+ bool points_changed;
+
+ // Draw a circle using openGL
+ void draw_circle(int x, int y, int r);
+
+ // Find the point which is under the mouse
+ int find_hovered_point();
+
+
+};
\ No newline at end of file
diff --git a/exercise4/include/curve_renderer.h b/exercise4/include/curve_renderer.h
new file mode 100644
index 0000000..6b4ceb3
--- /dev/null
+++ b/exercise4/include/curve_renderer.h
@@ -0,0 +1,59 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+The curve renderer.
+This class is responsible for rendering curves using OpenGL. The curve
+to render must implement the interface "abstract_curve" and is provided
+via the "set_curve" method. The method "render_curve" performs the
+rendering. Whenever the curve changes the method "sample_curve" is called
+which samples the curve at equidistant intervals of the domain parameter "t".
+The number of samples can be specified using the parameter "sample_count".
+For rendering the basis functions the method "render_basis_functions" is
+provided which also invokes the method "render_basis_axes" for rendering
+the coordinate system.
+*************************************************************************/
+
+#pragma once
+
+// provides the abstract curve interface
+#include "abstract_curve.h"
+
+class curve_renderer
+{
+public:
+ // Initialize the curve renderer
+ curve_renderer();
+
+ // Sample the curve using "sample_count" samples and store the
+ // result in the list "samples".
+
+ void sample_curve(int sample_count);
+ // Set the active curve to render
+ void set_curve(abstract_curve *curve);
+
+
+ // Render the curve
+ void render_curve();
+
+ // Render the basis functions
+ void render_basis_functions();
+
+private:
+ // The curve to render
+ abstract_curve *curve;
+
+ // A list of samples of the curve
+ std::vector samples;
+
+ // The width and height of the coordinate system of the basis functions
+ int basis_width, basis_height;
+
+
+ // Render the basis functions coordinate system
+ void render_basis_axes();
+ // Set an OpenGL color for a basis function "i"
+ void set_basis_color(int i);
+};
\ No newline at end of file
diff --git a/exercise4/include/hermite_spline.h b/exercise4/include/hermite_spline.h
new file mode 100644
index 0000000..ed45ad6
--- /dev/null
+++ b/exercise4/include/hermite_spline.h
@@ -0,0 +1,38 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+A simple hermite curve.
+This class uses the interface "abstract_curve" to define a hermite curve.
+Read the information in "abstract_curve.h" for more details.
+*************************************************************************/
+
+#pragma once
+
+// provides the abstract curve interface
+#include "abstract_curve.h"
+
+
+
+class hermite_spline: public abstract_curve
+{
+public:
+ // Initialize the curve and store a reference of the control points
+ hermite_spline(std::vector& control_points);
+
+ // The specified "evaluate" method to evaluate a curve point as a
+ // function of the domain parameter "t".
+ point2d evaluate(double t);
+
+ // The specified "evaluate_basis" to evaluate a basis function for
+ // the control point "point_num" at the position "t"
+ double evaluate_basis(int point_num, double t);
+
+
+ // The specified "set_text" method to put arbitrary text into the
+ // stream "stream"
+ void set_text(std::stringstream &stream);
+
+};
\ No newline at end of file
diff --git a/exercise4/include/lagrange_curve.h b/exercise4/include/lagrange_curve.h
new file mode 100644
index 0000000..d2efe21
--- /dev/null
+++ b/exercise4/include/lagrange_curve.h
@@ -0,0 +1,38 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+A lagrange curve.
+This class uses the interface "abstract_curve" to define a lagrange curve.
+Read the information in "abstract_curve.h" for more details.
+*************************************************************************/
+
+#pragma once
+
+// provides the abstract curve interface
+#include "abstract_curve.h"
+
+
+
+class lagrange_curve: public abstract_curve
+{
+public:
+ // Initialize the curve and store a reference of the control points
+ lagrange_curve(std::vector& control_points);
+
+ // The specified "evaluate_basis" to evaluate a basis function for
+ // the control point "point_num" at the position "t"
+ double evaluate_basis(int point_num, double t);
+
+
+ // The speficied "control_points_updated" to adjust the domain range
+ // as a function of the number of control points
+ void control_points_updated();
+
+ // The specified "set_text" method to put arbitrary text into the
+ // stream "stream"
+ void set_text(std::stringstream &stream);
+
+};
\ No newline at end of file
diff --git a/exercise4/include/tiny_vec.h b/exercise4/include/tiny_vec.h
new file mode 100644
index 0000000..940a061
--- /dev/null
+++ b/exercise4/include/tiny_vec.h
@@ -0,0 +1,970 @@
+//
+// This source code is property of the Computer Graphics and Visualization
+// chair of the TU Dresden. Do not distribute in modified or unmodified form!
+// Copyright (C) 2016 CGV TU Dresden - All Rights Reserved
+//
+/*************************************************************************
+Template class for vectors.
+This template class defines small vectors of a defined dimension with
+an arbitrary data type. Basic operations such as addition of vectors and
+multiplication of a vector and a scalar are supported via operator
+overloading. Also more advanced functions such as normalization and
+iterating through the elements are implemented.
+At the end of this file the data types "point2d", "point3d" and
+"point4d" are specified as a tinyvec of doubles with the according dimension.
+*************************************************************************/
+
+#pragma once
+
+
+
+
+#include
+#include
+#include
+#include
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4996 )
+#endif
+template
+class tiny_vec
+{
+
+ T _data[N];
+
+public:
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+ typedef std::reverse_iterator reverse_iterator;
+ typedef std::reverse_iterator const_reverse_iterator;
+
+ tiny_vec();
+
+ template
+ tiny_vec(InputIterator first,InputIterator last)
+ {
+ std::copy(first,last,begin());
+ }
+
+
+ tiny_vec(size_t n, const T* marray);
+
+ ~tiny_vec();
+
+ tiny_vec(const T&x,const T&y);
+
+ tiny_vec(const T&x,const T&y, const T&z);
+
+ tiny_vec(const T&x, const T&y, const T&z,const T& w);
+
+ int size() const;
+
+ operator T*();
+
+ operator const T*() const;
+
+ void set(const T& x);
+
+ void set(const T& x, const T& y);
+
+ void set(const T& x, const T& y,const T& z);
+
+ void set(const T& x, const T& y,const T& z, const T& w);
+
+ tiny_vec& operator=(const T &s);
+
+ tiny_vec& operator=(int s);
+
+ tiny_vec& operator=(const tiny_vec & v);
+
+ void fill(const T& s);
+
+ void zeros();
+
+ void ones();
+
+ iterator begin();
+
+ iterator end();
+
+ const_iterator begin() const;
+
+ const_iterator end() const;
+
+ reverse_iterator rbegin();
+
+ reverse_iterator rend();
+
+ const_reverse_iterator rbegin() const;
+
+ const_reverse_iterator rend() const;
+
+ bool operator==(const tiny_vec& v) const;
+
+ bool operator!=(const tiny_vec& v) const;
+
+ tiny_vec operator-() const;
+
+
+
+ tiny_vec& operator+=(int s);
+
+ tiny_vec& operator+=(float s);
+
+ tiny_vec& operator+=(double s);
+
+
+
+ tiny_vec operator+(int s) const;
+
+ tiny_vec operator+(float s) const;
+
+ tiny_vec operator+(double s) const;
+
+
+
+ tiny_vec& operator-=(int s);
+
+ tiny_vec& operator-=(float s);
+
+ tiny_vec& operator-=(double s);
+
+
+
+ tiny_vec operator-(int s) const;
+
+ tiny_vec operator-(float s) const;
+
+ tiny_vec operator-(double s) const;
+
+
+
+ tiny_vec& operator*=(int s);
+
+ tiny_vec& operator*=(float s);
+
+ tiny_vec& operator*=(double s);
+
+
+
+ tiny_vec operator*(int s) const;
+
+ tiny_vec operator*(float s) const;
+
+ tiny_vec operator*(double s) const;
+
+
+
+ tiny_vec& operator/=(int s);
+
+ tiny_vec& operator/=(float s);
+
+ tiny_vec& operator/=(double s);
+
+
+
+ tiny_vec operator/(int s) const;
+
+ tiny_vec operator/(float s) const;
+
+ tiny_vec operator/(double s) const;
+
+ tiny_vec& operator+=(const tiny_vec& v);
+
+ tiny_vec operator+(const tiny_vec& v) const;
+
+ tiny_vec& operator-=(const tiny_vec& v);
+
+ tiny_vec operator-(const tiny_vec& v) const;
+
+ tiny_vec& operator*=(const tiny_vec& v);
+
+ tiny_vec operator*(const tiny_vec& v) const;
+
+ tiny_vec& operator/=(const tiny_vec& v);
+
+ tiny_vec operator/(const tiny_vec& v) const;
+
+ T& operator()(size_t i);
+
+ T operator()(size_t i) const;
+
+ T& x() {return _data[0];};
+ T& y() {return _data[1];};
+ T& z() {return _data[2];};
+
+ T x() const {return _data[0];};
+ T y() const {return _data[1];};
+ T z() const {return _data[2];};
+
+
+ void sort();
+
+ void random_shuffle();
+
+ T& min_elem();
+
+ T min_elem() const;
+
+ size_t min_index() const;
+
+ T& max_elem();
+
+ T max_elem() const;
+
+ size_t max_index() const;
+
+ T& median_elem();
+
+ size_t median_index() const;
+
+ T sqr_length() const;
+
+ T length() const;
+
+ void normalize();
+
+};
+
+
+
+template
+tiny_vec::tiny_vec(){}
+
+
+template
+tiny_vec::tiny_vec(size_t n,const T* marray)
+{
+ std::copy(marray,marray+N,begin());
+}
+
+template
+tiny_vec::~tiny_vec(){}
+
+template
+tiny_vec::tiny_vec(const T&x,const T&y)
+{
+ _data[0]=x;
+ _data[1]=y;
+}
+
+template
+tiny_vec::tiny_vec(const T&x,const T&y, const T&z)
+{
+ _data[0]=x;
+ _data[1]=y;
+ _data[2]=z;
+}
+
+template
+tiny_vec::tiny_vec(const T&x, const T&y, const T&z,const T& w)
+{
+ _data[0]=x;
+ _data[1]=y;
+ _data[2]=z;
+ _data[3]=w;
+}
+
+template
+void tiny_vec::set(const T& x)
+{
+ _data[0]=x;
+}
+
+template
+void tiny_vec::set(const T& x, const T& y)
+{
+ _data[0]=x;
+ _data[1]=y;
+
+}
+template
+void tiny_vec::set(const T& x, const T& y,const T& z)
+{
+ _data[0]=x;
+ _data[1]=y;
+ _data[2]=z;
+
+}
+template
+void tiny_vec::set(const T& x, const T& y,const T& z, const T& w)
+{
+ _data[0]=x;
+ _data[1]=y;
+ _data[2]=z;
+ _data[3]=w;
+}
+
+template
+int tiny_vec::size() const
+{
+ return N;
+}
+
+template
+tiny_vec::operator T*()
+{
+ return _data;
+}
+
+
+template
+tiny_vec::operator const T*() const
+{
+ return _data;
+}
+
+template
+tiny_vec& tiny_vec::operator=(const T &s)
+{
+ for(int i=0;i < N;i++)
+ _data[i]=s;
+
+ return *this;
+}
+
+template
+tiny_vec& tiny_vec::operator=(int s)
+{
+ for(int i=0;i
+tiny_vec& tiny_vec::operator=(const tiny_vec & v)
+{
+ if(&v== this) return *this;
+
+ std::copy(v.begin(),v.end(),begin());
+ return *this;
+}
+
+
+
+template
+void tiny_vec::fill(const T& s)
+{
+ std::fill(begin(),end(),s);
+}
+
+
+
+template
+void tiny_vec::zeros()
+{
+ T zero;
+ zero=0;
+ std::fill(begin(), end(), zero);
+}
+
+template
+void tiny_vec::ones()
+{
+ T one;
+ one = 1;
+ std::fill(begin(), end(), one);
+}
+
+
+
+template
+typename tiny_vec::iterator tiny_vec::begin()
+{
+ return _data;
+}
+
+template
+typename tiny_vec::const_iterator tiny_vec::begin() const
+{
+ return _data;
+}
+
+template
+typename tiny_vec::iterator tiny_vec::end()
+{
+ return _data + N;
+}
+
+template
+typename tiny_vec::const_iterator tiny_vec::end() const
+{
+ return _data +N;
+}
+
+template
+typename tiny_vec::reverse_iterator tiny_vec::rbegin()
+{
+ return reverse_iterator(end());
+}
+
+template
+typename tiny_vec::reverse_iterator tiny_vec::rend()
+{
+ return reverse_iterator(begin());
+}
+
+template
+typename tiny_vec::const_reverse_iterator tiny_vec::rbegin() const
+{
+ return const_reverse_iterator(end());
+}
+
+template
+typename tiny_vec::const_reverse_iterator tiny_vec:: rend() const
+{
+ return const_reverse_iterator(begin());
+}
+
+template
+bool tiny_vec::operator==(const tiny_vec& v) const
+{
+ return std::equal(begin(),end(),v.begin());
+}
+
+
+template
+bool tiny_vec::operator!=(const tiny_vec& v) const
+{
+ return !(*this == v);
+}
+
+template
+tiny_vec tiny_vec::operator-() const
+{
+ return (T)-1* *this;
+}
+
+
+
+template
+tiny_vec& tiny_vec::operator+=(int s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator+=(float s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator+=(double s)
+{
+
+ for(int i=0;i
+tiny_vec tiny_vec::operator+(int s) const
+{
+ tiny_vec r = *this;
+ r += s;
+ return r;
+}
+
+
+template
+tiny_vec tiny_vec::operator+(float s) const
+{
+ tiny_vec r = *this;
+ r += (T)s;
+ return r;
+}
+
+template
+tiny_vec tiny_vec::operator+(double s) const
+{
+ tiny_vec r = *this;
+ r += (T)s;
+ return r;
+}
+
+
+
+template
+tiny_vec& tiny_vec::operator-=(int s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator-=(float s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator-=(double s)
+{
+
+ for(int i=0;i
+tiny_vec tiny_vec::operator-(int s) const
+{
+ tiny_vec r = *this;
+ r -= (T)s;
+ return r;
+}
+
+
+
+template
+tiny_vec tiny_vec::operator-(float s) const
+{
+ tiny_vec r = *this;
+ r -= (T)s;
+ return r;
+}
+
+
+
+template
+tiny_vec tiny_vec::operator-(double s) const
+{
+ tiny_vec r = *this;
+ r -= (T)s;
+ return r;
+}
+
+
+
+template
+tiny_vec& tiny_vec::operator*=(int s)
+{
+ for(int i=0; i
+tiny_vec& tiny_vec::operator*=(float s)
+{
+ for(int i=0; i
+tiny_vec& tiny_vec::operator*=(double s)
+{
+ for(int i=0; i
+tiny_vec tiny_vec::operator*(int s) const
+{
+ tiny_vec r = *this;
+ r *= (T)s;
+ return r;
+}
+
+template
+tiny_vec tiny_vec::operator*(float s) const
+{
+ tiny_vec r = *this;
+ r *= (T)s;
+ return r;
+}
+
+template
+tiny_vec tiny_vec::operator*(double s) const
+{
+ tiny_vec r = *this;
+ r *= (T)s;
+ return r;
+}
+
+
+
+template
+tiny_vec& tiny_vec::operator/=(int s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator/=(float s)
+{
+
+ for(int i=0;i
+tiny_vec& tiny_vec::operator/=(double s)
+{
+
+ for(int i=0;i
+tiny_vec tiny_vec::operator/(int s) const
+{
+ tiny_vec r = *this;
+ r /= (T)s;
+ return r;
+}
+
+template
+tiny_vec tiny_vec::operator/(float s) const
+{
+ tiny_vec r = *this;
+ r /= (T)s;
+ return r;
+}
+
+template
+tiny_vec tiny_vec::operator/(double s) const
+{
+ tiny_vec r = *this;
+ r /= (T)s;
+ return r;
+}
+
+template
+tiny_vec& tiny_vec::operator+=(const tiny_vec& v)
+{
+
+ for(int i=0; i
+tiny_vec tiny_vec::operator+(const tiny_vec& v) const
+{
+ tiny_vec r = *this;
+ r += v;
+ return r;
+}
+
+
+template
+tiny_vec& tiny_vec::operator-=(const tiny_vec& v)
+{
+ for(int i =0; i < N; i++)
+ _data[i]-= v[i];
+
+ return *this;
+}
+
+
+template
+tiny_vec tiny_vec::operator-(const tiny_vec& v) const
+{
+ tiny_vec r = *this;
+ r -= v;
+ return r;
+}
+
+
+template
+tiny_vec& tiny_vec::operator*=(const tiny_vec& v)
+{
+ for(int i=0; i < N; i++)
+ _data[i]*= v[i];
+ return *this;
+}
+
+
+template
+tiny_vec tiny_vec::operator*(const tiny_vec& v) const
+{
+ tiny_vec r = *this;
+ r *= v;
+ return r;
+}
+
+
+template
+tiny_vec& tiny_vec::operator/=(const tiny_vec& v)
+{
+ for(int i = 0; i < N; i++)
+ _data[i] /= v[i];
+
+ return *this;
+}
+
+
+template
+tiny_vec tiny_vec::operator/(const tiny_vec& v) const
+{
+ tiny_vec r = *this;
+ r /= v;
+ return r;
+}
+
+
+template
+T& tiny_vec::operator()(size_t i)
+{
+ assert(i >= 0 && i < N);
+ return _data[i];
+}
+
+template
+T tiny_vec::operator()(size_t i) const
+{
+ assert(i >= 0 && i < N);
+ return _data[i];
+}
+
+template
+void tiny_vec::sort()
+{
+ std::sort(begin(),end());
+}
+
+template
+void tiny_vec::random_shuffle()
+{
+ std::random_shuffle(begin(),end());
+}
+
+template
+T& tiny_vec::min_elem()
+{
+ return *std::min_element(begin(),end());
+}
+
+template
+T tiny_vec::min_elem() const
+{
+ return *std::min_element(begin(),end());
+}
+
+template
+size_t tiny_vec::min_index() const
+{
+ return std::distance(begin(),std::min_element(begin(),end()));
+}
+
+template
+T& tiny_vec::max_elem()
+{
+ return *std::max_element(begin(),end());
+}
+
+template
+T tiny_vec::max_elem() const
+{
+ return *std::max_element(begin(),end());
+}
+
+template
+size_t tiny_vec::max_index() const
+{
+ return std::distance(begin(),std::max_element(begin(),end()));
+}
+
+
+template
+T tiny_vec::sqr_length() const
+{
+ iterator it= (double*)begin();
+ T l = 0;
+ while(it != end())
+ l += (*it)*(*it++);
+
+ return l;
+}
+
+template
+T tiny_vec::length() const
+{
+ T l = sqr_length();
+ return sqrt(l);
+}
+
+
+template
+tiny_vec operator+(const T& s, const tiny_vec& v)
+{
+ return v+s;
+}
+
+
+template
+tiny_vec operator+(int s, const tiny_vec& v)
+{
+ return v+(T)s;
+}
+
+template
+tiny_vec operator-(const T& s, const tiny_vec& v)
+{
+ return -v+s;
+}
+
+
+template
+tiny_vec operator-(int s, const tiny_vec& v)
+{
+ return -v+(T)s;
+}
+
+
+template
+tiny_vec operator*(const T& s, const tiny_vec& v)
+{
+ return v*s;
+}
+
+
+template
+tiny_vec