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 operator*(int s, const tiny_vec& v) +{ + return v*(T)s; +} + +template +tiny_vec operator/(const T& s, const tiny_vec& v) +{ + return v*(T)(1.0/s); +} + +template +tiny_vec operator/(int s, const tiny_vec& v) +{ + return v*(T)(1.0/s); +} + +template +T dot(const tiny_vec& v1, const tiny_vec& v2) +{ + return std::inner_product(v1.begin(),v1.end(),v2.begin(),(T)0); +} + + + +template +tiny_vec cross(const tiny_vec& b, const tiny_vec& c) +{ + tiny_vec a; + a[0] = b(1)*c(2) - b(2)*c(1); + a[1] = b(2)*c(0) - b(0)*c(2); + a[2] = b(0)*c(1) - b(1)*c(0); + return a; +} + + +template +tiny_vec homog(const tiny_vec& v) +{ + tiny_vec vh; + std::copy(v.begin(),v.end(),vh.begin()); + vh(v.size()) = (T)1; + return vh; +} + +template +tiny_vec unhomog(const tiny_vec& v) +{ + tiny_vec vh; + T w = *(v.end()-1); + + for(int i = 0; i < N-1; i++) + vh[i] = v[i]/w; + + return vh; +} + + + + +template +std::ostream& operator<<(std::ostream& out, const tiny_vec& v) +{ + if(v.size() > 0) + out << v[0]; + for(int i = 1; i < v.size(); i++) + out <<" " < +std::istream& operator>>(std::istream& in, tiny_vec& v) +{ + for(int i = 0; i < v.size(); i++) + in >> v[i]; + + return in; +} + +template +void tiny_vec::normalize() +{ + T l = length(); + if(l != 0) + operator/=(l); +} + + + +typedef tiny_vec point2d; +typedef tiny_vec point3d; +typedef tiny_vec point4d; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +typedef tiny_vec vec2d; +typedef tiny_vec vec3d; +typedef tiny_vec vec4d; diff --git a/exercise4/solution.exe b/exercise4/solution.exe new file mode 100644 index 0000000..9f3c987 Binary files /dev/null and b/exercise4/solution.exe differ diff --git a/exercise4/src/abstract_curve.cpp b/exercise4/src/abstract_curve.cpp new file mode 100644 index 0000000..7625d16 --- /dev/null +++ b/exercise4/src/abstract_curve.cpp @@ -0,0 +1,99 @@ +// +// 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 +// +#include "abstract_curve.h" + +// Initialize the curve and store a reference of the control points +abstract_curve::abstract_curve(std::vector &control_points): control_points(control_points) +{ + t_min = 0; + t_max = 1; +} + +abstract_curve::~abstract_curve() {} + + +// Evaluate the curve at "t" +point2d abstract_curve::evaluate(double t) +{ + point2d sample(0.0, 0.0); + + /************** + Task 4.1.1. Implement the functionality to evaluate a point on the curve + at the parameter value "t". The point is calculated by summing + all control points weightened with their basis function at "t". + Store the result into the variable "sample". To get the ith control + point use "control_points[i]". You can get the number of + control points with "control_points.size()". Use the command + "evaluate_basis" to get the basis function value for a control + point at "t". The point2d class supports operations such as addition + or multiplication with a scalar value. Below are some sample codes. + Aufgabe 4.4.1. Implementieren Sie die Auswertung eines Punktes auf der Kurve fuer + den Parameterwert "t". Ein Kurvenpunkt ist die Summe aller Kontroll- + Punkte, gewichtet mit deren Basisfunktionen bei "t". Speichern Sie + das Ergebnis in der Variable "sample". Um den i-ten Kontrollpunkt zu + erhalten nutzen Sie "control_points[i]". Die Anzahl der Kontrollpunkte + koennen Sie mittels "control_points.size()" ermitteln. Verwenden Sie die + Methode "evaluate_basis" um den Wert der Basisfunktion eines Kontrollpunktes + an der Stelle "t" zu erhalten. Die point2d-Klasse unterstuetzt Operatoren + wie Addition oder Multiplikation mit skalaren Werten. Einige Beispiele: + + // define a point + point2d pnt(0.0, 0.0); + // define another point + point2d pnt2 = 2.0*pnt; + // add points + pnt += 3.0*pnt2; + **********/ + + return sample; +} + + + +// Get the minimum value of the domain +double abstract_curve::get_min_t() +{ + return t_min; +} + + + + +// Get the maximum value of the domain +double abstract_curve::get_max_t() +{ + return t_max; +} + + + + +// Get a constant list of control points +const std::vector& abstract_curve::get_control_points() const +{ + return control_points; +} + + + + +// Shall be called whenever the control point set changes +void abstract_curve::control_points_updated() +{ + // ... does nothing and should be specified in inherited classes + // if needed. +} + + + + +// Put a text into the stream "stream" which will be displayed +// in the main window +void abstract_curve::set_text(std::stringstream &stream) +{ + // ... does nothing and should be specified in inherited classes + // if needed. +} diff --git a/exercise4/src/application.cpp b/exercise4/src/application.cpp new file mode 100644 index 0000000..def877c --- /dev/null +++ b/exercise4/src/application.cpp @@ -0,0 +1,444 @@ +// +// 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 +// +#include "application.h" + +#include + +#include "bezier_curve.h" +#include "bspline.h" +#include "lagrange_curve.h" +#include "hermite_spline.h" + + + +application::application() +{ + instance = this; + + // Set initial parameters + curve_resolution = 1000; + spline_degree = 2; + show_basis_functions = false; + show_grid = true; + menu_dirty = true; + + // Put 3 points into the list of control points + control_points.push_back(point2d(100.0, 400.0)); + control_points.push_back(point2d(200.0, 50.0)); + control_points.push_back(point2d(550.0, 200.0)); + + // Initialize the curve, the renderer and the editor + curve = 0; + ctl_editor = new control_points_editor(control_points); + renderer = new curve_renderer(); +} + + + +application::~application() +{ + // Delete all allocated variables + delete ctl_editor; + delete curve; + delete renderer; +} + + + + +// Run the program using the command line arguments +int application::run(int argc, char* argv[]) +{ + // Initialize the GLUT system and let it evaluate additional + // command line arguments. + glutInit(&argc, argv); + + // Set the openGL display mode to double buffering and have + // channels R,G,B active. + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + + // Initialize main window size + glutInitWindowSize(640, 480); + // Set a title + glutCreateWindow("ECG Kurven"); + + // Set the context menu + setup_context_menu(); + + // Initialize the curve + context_menu_select(MA_LAGRANGE_CURVE); + + // The following section tells GLUT which methods to call + // whenever certain events happen. + // ... when the screen shall be displayed + glutDisplayFunc(display_callback); + // ... when a key was pressed + glutKeyboardFunc(key_down_callback); + // ... when a mouse button was pressed + glutMouseFunc(mouse_button_callback); + // ... when the mouse was moved with buttons pressed + glutMotionFunc(mouse_move_callback); + // ... when the mouse was moved without buttons pressed + glutPassiveMotionFunc(mouse_move_callback); + // ... when the menu state changes + glutIdleFunc(idle_callback); + + // The main loop runs the program itself. It repeatedly asks + // the operating system whether there are events to process + // and, according to the type of the event, calls the right + // method (that was defined above). + glutMainLoop(); + + return 0; +} + + + +void application::set_curve_type(abstract_curve *c) +{ + // Delete the old curve if there is one, + // set the parameter to be the active curve and + // update the renderer. + if (curve) + delete curve; + curve = c; + curve->control_points_updated(); + renderer->set_curve(curve); + renderer->sample_curve(curve_resolution); +} + + + + +// The event method on context menu selections +void application::context_menu_select(int item) +{ + switch(item) + { + // Set bezier curve + case MA_BEZIER_CURVE: + set_curve_type(new bezier_curve(control_points)); + break; + + // Set lagrange curve + case MA_LAGRANGE_CURVE: + set_curve_type(new lagrange_curve(control_points)); + break; + + // Set hermite curve + case MA_hermite_spline: + set_curve_type(new hermite_spline(control_points)); + break; + + // Set bspline + case MA_BSPLINE: + set_curve_type(new bspline(control_points, spline_degree)); + break; + + // Activate or deactivate rendering of basis functions + case MA_SHOW_BASIS: + show_basis_functions = !show_basis_functions; + menu_dirty = true; + break; + + // Increase the degree + case MA_INCREASE_DEGREE: + spline_degree++; + // If the active curve is of type "bspline" then recreate it + // using the new degree + if (dynamic_cast(curve)) + set_curve_type(new bspline(control_points, spline_degree)); + menu_dirty = true; + break; + + // Decrease the degree + case MA_DECREASE_DEGREE: + if (spline_degree>1) + spline_degree--; + // If the active curve is of type "bspline" then recreate it + // using the new degree + if (dynamic_cast(curve)) + set_curve_type(new bspline(control_points, spline_degree)); + menu_dirty = true; + break; + + // Delete control points + case MA_DELETE_CTL_POINTS: + control_points.clear(); + // Tell the curve and the renderer that the points changed + curve->control_points_updated(); + renderer->sample_curve(curve_resolution); + break; + + // Show or hide the grid + case MA_SHOW_GRID: + show_grid = !show_grid; + menu_dirty = true; + break; + } + + // Update display + display(); +} + + + + +// Initialize the context menu +void application::setup_context_menu() +{ + glutCreateMenu(context_menu_callback); + + // Set the menu entries and associate them with the + // appropriate menu action ID + glutAddMenuEntry(" Connect with lagrange curve (l) ", MA_LAGRANGE_CURVE); + glutAddMenuEntry(" Connect with bezier curve (b) ", MA_BEZIER_CURVE); + glutAddMenuEntry(" Connect with hermite curve (h) ", MA_hermite_spline); + glutAddMenuEntry(" Connect with spline (s) ", MA_BSPLINE); + // The name for menu entries which can change + // (that means e.g. can have "[ ]" or "[X]") are set in "update_context_menu + glutAddMenuEntry("", MA_SHOW_BASIS); + glutAddMenuEntry(" ----- Spline Settings ----- ", -1); + glutAddMenuEntry("", MA_INCREASE_DEGREE); + glutAddMenuEntry("", MA_DECREASE_DEGREE); + glutAddMenuEntry(" ------ Miscellaneous ------ ", -1); + glutAddMenuEntry("", MA_SHOW_GRID); + glutAddMenuEntry(" Delete control points (c) ", MA_DELETE_CTL_POINTS); + + // Attach the menu to the right mouse button + glutAttachMenu(GLUT_RIGHT_BUTTON); + + // Initially fill in the missing menu entry names + update_context_menu(); +} + + + + +void application::update_context_menu() +{ + std::stringstream mname; + + // Update the basis function menu point and display a + // [X] or [ ] at the beginning according to the setting + mname.str(""); + if (show_basis_functions) + mname<<"[X]"; + else + mname<<"[ ]"; + mname<<" Show basis functions (f) "; + glutChangeToMenuEntry(5, mname.str().c_str(), MA_SHOW_BASIS); + + // Update the spline degree menus and show the degree + // in square brackets + mname.str(""); + mname<<"["<control_points_changed()) { + curve->control_points_updated(); + renderer->sample_curve(curve_resolution); + } + + if (show_grid) + render_grid(); + + // Draw the control polygon + ctl_editor->draw_control_polygon(); + // On top render the curve + renderer->render_curve(); + // And on top of this render the control points + ctl_editor->draw_control_points(); + + // Eventually show the basis functions + if (show_basis_functions) + renderer->render_basis_functions(); + + // ... and the debug output + std::stringstream stream; + curve->set_text(stream); + glColor3d(0.0, 0.0, 0.0); + // Go to the bottom left of the window + glRasterPos2i(10, glutGet(GLUT_WINDOW_HEIGHT)-10); + glutBitmapString(GLUT_BITMAP_HELVETICA_12, reinterpret_cast(stream.str().c_str())); + + // Swap the just filled backbuffer with the front buffer + // to display the result + glutSwapBuffers(); +} + + + + +// Render a regular grid +void application::render_grid() +{ + // Store the width and height of the window for easier access + int width = glutGet(GLUT_WINDOW_WIDTH); + int height = glutGet(GLUT_WINDOW_HEIGHT); + + // The grid size in pixels + const int grid_size = 25; + + // Enable line stippling to render dotted lines + glEnable(GL_LINE_STIPPLE); + // Define the stipple pattern. The pattern is 0x8888 which is + // 1000100010001000 in binary (draw one pixel and then skip three). + // Every bit shall be used 1x consecutively. + glLineStipple(1, 0x8888); + + // Set color to light gray + glColor3d(0.8, 0.8, 0.8); + + // Render the horizontal lines + glBegin(GL_LINES); + for (int i=0; imouse_button(button, state); + + display(); +} + + + + +// The event method on mouse motions +void application::mouse_move(int x, int y) +{ + // Just handled over to the control points editor + ctl_editor->mouse_move(x, y); + + display(); +} + + + + + + +application *application::instance = 0; + + +void application::key_down_callback(unsigned char key, int x, int y) +{ + instance->key_down(key, x, y); +} + +void application::mouse_button_callback(int button, int state, int x, int y) +{ + instance->mouse_button(button, state); +} + +void application::mouse_move_callback(int x, int y) +{ + instance->mouse_move(x, y); +} + +void application::display_callback() +{ + instance->display(); +} + +void application::context_menu_callback(int item) +{ + instance->context_menu_select(item); +} + +void application::idle_callback() +{ + if(instance->menu_dirty) + instance->update_context_menu(); +} \ No newline at end of file diff --git a/exercise4/src/bezier_curve.cpp b/exercise4/src/bezier_curve.cpp new file mode 100644 index 0000000..7d8b4e4 --- /dev/null +++ b/exercise4/src/bezier_curve.cpp @@ -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 +// +#include "bezier_curve.h" +#include + + +// Initialize the curve and store a reference of the control points +bezier_curve::bezier_curve(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// A helper function to calculate "n choose k" +double bezier_curve::binomial_coefficient(int n, int k) +{ + // ... functionality to be added! + + // Remove and replace me with the right return value + return 0.0; +} + + + + +// Evaluate a basis as a function of the control point "point_num" +// (counted from zero) and the domain parameter t +double bezier_curve::evaluate_basis(int point_num, double t) +{ + int n = control_points.size()-1; + int i = point_num; + + /********** + Task 4.1.4. Implement the evaluation of the Bernstein basis. You can use + the method "binomial_coefficient" above (which must also be + implemented) for the calculation if wanted. + Aufgabe 4.1.4. Implementieren Sie die Auswertung der Bernsteinbasis. Sie koennen + die Methode "binomial_coeffizient" von oben (die allerdings + ebenfalls noch nicht implementiert ist) fuer die Berechnung + nutzen. + ************/ + + + // Remove and replace me with the right return value + return 0.0; +} + + + +// Set debug text +void bezier_curve::set_text(std::stringstream &stream) +{ + stream<<"Type: Bezier"; +} \ No newline at end of file diff --git a/exercise4/src/bspline.cpp b/exercise4/src/bspline.cpp new file mode 100644 index 0000000..a5e9278 --- /dev/null +++ b/exercise4/src/bspline.cpp @@ -0,0 +1,103 @@ +// +// 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 +// +#include "bspline.h" + +// Initialize the curve and store a reference of the control points. +// Also the degree of the curve is provided through this constructor +bspline::bspline(std::vector& control_points, int degree): +abstract_curve(control_points) +{ + this->degree = degree; +} + + + + +// The specified "control_points_updated" to adjust the knot vector +// when control points are added or removed +void bspline::control_points_updated() +{ + // Update the knot vector + calculate_knot_vector(); + + // Set the valid range for "t" + if (u.size() != 0) { + t_min = u[0]; + t_max = u[u.size()-1]; + } +} + + + + +// Calculate the knot vector. This method is called from +// "control_points_updated" +void bspline::calculate_knot_vector() +{ + // Initialize variables according to the script + int K = control_points.size(); + int g = degree; + int n = K - g; + + // Clear and resize the knot vector to the right size + u.clear(); + u.resize(K + g + 1); + + /************* + Task 4.1.6. Fill the knot vector u with the appropriate values for + open splines with end point interpolation. The above code + initializes variables according to the script. + Aufgabe 4.1.6. Fuellen Sie den Knotenvektor u mit den passenden Werten + fuer offene Splines mit Endpunktinterpolation. Der obige + Code initialisiert Variablen wie sie im Skript zu finden sind. + *************/ +} + + + + +// Evaluate the basis as a function of the control point "point_num" +// (counted from zero) and the parameter "t". +double bspline::evaluate_basis(int point_num, double t) +{ + /********** + Task 4.1.6. Implement the evaluation of the basis function of bsplines + for the control point "point_num" at "t". You will find + another version with specifyable degree below which you can + call from here and use if you want to implement the recursive + approach. The degree of this spline is stored in the variable "degree". + Aufgabe 4.1.6. Implementieren Sie die Auswertung der Basisfunktion eines + BSpline fuer den Kontrollpunkt "point_num" an der Stelle "t". + Unten finden Sie eine andere Version mit einstellbarem Grad, + die Sie von hier aus aufrufen und verwenden koennen um den rekursiven + Berechnungsansatz umzusetzen. + ***********/ + + + // Remove and replace me with the right return value + return 0.0; +} + + + + +// 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 bspline::evaluate_basis(int g, int i, double t) +{ + + // Remove and replace me with the right return value + return 0.0; +} + + + +// Set debug text +void bspline::set_text(std::stringstream &stream) +{ + stream<<"Type: BSpline (with degree "< + + +// Constructor. Set the reference to the provided list +control_points_editor::control_points_editor(std::vector &control_points): +control_points(control_points) +{ + last_x = 0; + last_y = 0; + selected_point = -1; + hovered_point = -1; + points_changed = false; +} + + + + +// Find the control point that is under the mouse +int control_points_editor::find_hovered_point() +{ + std::vector::const_iterator iter; + int num = 0; + + // Go through all control points + for (iter = control_points.begin(); iter != control_points.end(); iter++) { + // Calculate the distance from one control point to the mouse position + double dist = sqrt((last_x - iter->x()) * (last_x - iter->x()) + (last_y - iter->y())*(last_y - iter->y())); + + // If the distance is less than 5 then we are in the circle that + // represents one control point. + if (dist<5) + return num; + + num++; + } + + // Since we are here no control point was found, so return -1 + return -1; +} + + + + +// Method to be called whenever the mouse moves +void control_points_editor::mouse_move(int x, int y) +{ + // Store the mouse position for later use + last_x = x; + last_y = y; + + points_changed = false; + + // If currently no point is selected then check whether + // the mouse hovers a point + if (selected_point == -1) + hovered_point = find_hovered_point(); + else { + // Otherwise update the position of the selected point + // and mark the control points list as changed + control_points[selected_point].x() = last_x; + control_points[selected_point].y() = last_y; + points_changed = true; + } +} + + + + +// Method to be called whenever a mouse button is pressed or released +void control_points_editor::mouse_button(int button, int state) +{ + points_changed = false; + + // We are just interested in events from the left button + if (button != GLUT_LEFT_BUTTON) + return; + + // If the button was pressed... + if (state == GLUT_DOWN) { + + // If shift was pressed and a point is hovered then + // erase the currently hovered point, mark the point set + // as changed and jump out of this method. + if ((glutGetModifiers() & GLUT_ACTIVE_SHIFT) && hovered_point != -1) { + control_points.erase(control_points.begin() + hovered_point); + hovered_point = -1; + points_changed = true; + return; + } + + // If the mouse is over a point then this is the point + // to be moved from now on + if (hovered_point != -1) + selected_point = hovered_point; + else { + // Otherwise a new point will be created and it is + // indicated that the point list has changed. + control_points.push_back(point2d((double)last_x, (double)last_y)); + selected_point = control_points.size()-1; + points_changed = true; + } + } + + // If the left mouse button was released then no point + // is selected for movements anymore. + if (state == GLUT_UP) + selected_point = -1; +} + + + + +// Return true if the control points list changed +bool control_points_editor::control_points_changed() +{ + bool old_points_changed = points_changed; + + points_changed = false; + + return old_points_changed; +} + + + +// Draw the control polygon +void control_points_editor::draw_control_polygon() +{ + std::vector::const_iterator iter; + + glColor3d(0.8, 0.8, 0.8); + + glBegin(GL_LINE_STRIP); + for (iter = control_points.begin(); iter != control_points.end(); iter++) + glVertex3d(iter->x(), iter->y(), 0.0); + glEnd(); +} + + + + + +// Draw the control points +void control_points_editor::draw_control_points() +{ + std::vector::const_iterator iter; + int num = 0; + + // Go through all control points + for (iter = control_points.begin(); iter != control_points.end(); iter++) { + + // Draw a black filled circle where the control point is + glColor3d(0,0,0); + draw_circle(static_cast(iter->x()), static_cast(iter->y()), 5); + + // Set the color to red if the current point is selected + if (num == selected_point || num == hovered_point) + glColor3d(1, 0, 0); + // ... or to white if not + else + glColor3d(1, 1, 1); + + // Draw a smaller circle inside the black one. + draw_circle(static_cast(iter->x()), static_cast(iter->y()), 4); + + num++; + } +} + + + +// Draw a circle. +void control_points_editor::draw_circle(int x, int y, int r) +{ + // Draw a circle by generating a circular polygon. Every vertex is a + // point on a circle with a distance of 10 degree. + // As the sin and cos function take arguments in radiants rather than + // in degree a conversion has to be made. + glBegin(GL_POLYGON); + for (int angle = 0; angle<360; angle+=10) + glVertex3d(x + sin(static_cast(angle)/180.0*M_PI)*r, y + cos(static_cast(angle)/180.0*M_PI)*r, 0); + glEnd(); +} \ No newline at end of file diff --git a/exercise4/src/curve_renderer.cpp b/exercise4/src/curve_renderer.cpp new file mode 100644 index 0000000..4a2dbac --- /dev/null +++ b/exercise4/src/curve_renderer.cpp @@ -0,0 +1,184 @@ +// +// 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) 2015 CGV TU Dresden - All Rights Reserved +// +#include "curve_renderer.h" + +#include "GL/glut.h" +#include "GL/freeglut_ext.h" + + +// Initialize the curve renderer +curve_renderer::curve_renderer() +{ + // no curve yet + curve = 0; + + // Width and heigth of the basis function graph + basis_width = 300; + basis_height = 100; +} + + +// Set the active curve to render +void curve_renderer::set_curve(abstract_curve *curve) +{ + this->curve = curve; +} + + + +// Sample the curve using "sample_count" samples and store the +// result in the list "samples". +void curve_renderer::sample_curve(int sample_count) +{ + samples.clear(); + + // Nothing to sample if there are not at least 2 control points + if (curve->get_control_points().size()<2) + return; + + /*************** + Task 4.1.2. Fill the list "samples" with "sample_count" curve points that + are equally sampled along the domain of "t". Mind that this + domain does not always have to range from 0 to 1. You will find + helper methods in "abstract_curve.h". To add a point to the list + use the "push_back"-Method of the "samples"-object. + Aufgabe 4.1.2. Fuellen Sie die Liste "samples" mit "sample_count" Kurvenpunkten, + die gleichmaessig ueber den Wertebereich von "t" verteilt sind. + Beachten Sie, dass dieser Wertebereich nicht zwingend von 0 bis + 1 gehen muss. Sie finden Helfermethoden in "abstract_curve.h". + Um einen Punkt in die Liste hinzuzufuegen nutzen Sie die + "push_back"-Methode des "samples"-Objektes. + ****************/ + + + // Remove the following lines + double step = (curve->get_max_t() - curve->get_min_t()) / 10; + + if (step<=0.0) + return; + + for (double t=curve->get_min_t(); t<=curve->get_max_t(); t+=step) + std::cout<<"t: "<evaluate(t)<get_max_t(); + if (t_max<=0.0) + t_max = 1.0; + + std::stringstream s; + s<(s.str().c_str())); + + glPopMatrix(); +} + + +// A helper function you can use to set a color for the basis function +void curve_renderer::set_basis_color(int i) +{ + i++; + // Set the color according to the basis function to render + glColor3d(i%2, (i%3)/2.0, (i%5)/6.0); +} + + + +// Render the basis functions +void curve_renderer::render_basis_functions() +{ + double t_max = curve->get_max_t(); + + // Only render the axes if the range is too small + if (t_max <=0.0) { + render_basis_axes(); + return; + } + + // Translate to the lower bottom of the screen and scale + // into the local coordinate system of the basis function graph + glPushMatrix(); + glTranslated(glutGet(GLUT_WINDOW_WIDTH) - basis_width - 10, glutGet(GLUT_WINDOW_HEIGHT) - basis_height - 10, 0); + glScaled(basis_width/t_max, -basis_height, 1); + + + /********** + Task 4.1.3. Render the basis functions of the curve "curve" by rendering + a consecutive line for every function. To set the color you + can use the method "set_basis_color" with the index of the + basis function as parameter. The system is already translated + and scaled so you can use "t" and the value of the basis function + directly as inputs for the line segments. + Aufgabe 4.1.3. Rendern Sie die Basisfunktionen der Kurve "curve" indem Sie fuer + jede Basisfunktion eine geschlossene Linie zeichnen lassen. Um + eine Zeichenfarbe zu setzen koennen Sie die Methode "set_basis_color" + verwenden, welcher der Index der darzustellenden Basisfunktionen als + Parameter mitgegeben wird. Das Koordinatensystem ist bereits so + verschoben und skaliert, dass Sie die Werte fuer "t" und die der + Basisfunktionen direkt als Eingaben fuer die Liniensegmente verwenden + koennen. + ************/ + + + + + + + + + glPopMatrix(); + + + // Render the axes + render_basis_axes(); +} \ No newline at end of file diff --git a/exercise4/src/hermite_spline.cpp b/exercise4/src/hermite_spline.cpp new file mode 100644 index 0000000..be477d9 --- /dev/null +++ b/exercise4/src/hermite_spline.cpp @@ -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) 2015 CGV TU Dresden - All Rights Reserved +// +#include "hermite_spline.h" +#include + + +// Initialize the curve and store a reference of the control points +hermite_spline::hermite_spline(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// Evaluate the curve at "t" +point2d hermite_spline::evaluate(double t) +{ + int n = control_points.size(); + + /********* + Task 4.1.5. Implement the evaluation of a spline point. A point + is built using the control points and their tangents. You + only have to do the calculation for one spline segment. + See the script for the calculation of points for one segment. + Aufgabe 4.1.5. Implementieren Sie die Auswertung eines Spline-Punktes. Dieser + wird ueber die Kontrollpunkte und Tangenten bestimmt. Die Berechnung + soll lediglich fuer ein Segment erfolgen. Im Skript finden Sie + genauere Informationen dazu. + ***********/ + + + + + // Remove and replace me with the right return value + return point2d(0.0, 0.0); +} + + + + +// Evaluate a basis as a function of the control point "point_num" +// (counted from zero) and the domain parameter t +double hermite_spline::evaluate_basis(int point_num, double t) +{ + /*********** + Task 4.1.5. Implement the evaluation of the basis function for the + point "point_num" at "t". You will find the formulas for + one segment directly in the script. Use the appropriate + formula for the right value of "point_num". + Aufgabe 4.1.5. Implementieren Sie die Auswertung der Basisfunktion des + Punktes "point_num" an der Stelle "t". Sie finden die + Formeln fuer ein Segment im Skript. Verwenden Sie fuer + jeden Wert von "point_num" die entsprechende Berechnungs- + Vorschrift. + ***********/ + + // Remove and replace me with the right return value + return 0.0; +} + + + +// Set debug text +void hermite_spline::set_text(std::stringstream &stream) +{ + stream<<"Type: Hermite (simple)"; +} \ No newline at end of file diff --git a/exercise4/src/lagrange_curve.cpp b/exercise4/src/lagrange_curve.cpp new file mode 100644 index 0000000..3b29cd2 --- /dev/null +++ b/exercise4/src/lagrange_curve.cpp @@ -0,0 +1,49 @@ +// +// 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) 2015 CGV TU Dresden - All Rights Reserved +// +#include "lagrange_curve.h" + +lagrange_curve::lagrange_curve(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// Called when the control points change. +void lagrange_curve::control_points_updated() +{ + // Update the valid range for "t" according to the + // number of control points + t_max = control_points.size()-1; + if (t_max<0) + t_max = 0; +} + + + + +// Evaluate a basis as a function of the control point "point_num" +// (counted from zero) and the domain parameter t +double lagrange_curve::evaluate_basis(int point_num, double t) +{ + double result = 1.0; + + for (int i=0; i<(int)control_points.size(); i++) + if (i != point_num) + result *= (t - i)/(point_num-i); + + return result; +} + + + + +// Set debug text +void lagrange_curve::set_text(std::stringstream &stream) +{ + stream<<"Type: Lagrange"; +} \ No newline at end of file diff --git a/exercise4/src/main.cpp b/exercise4/src/main.cpp new file mode 100644 index 0000000..303a9d9 --- /dev/null +++ b/exercise4/src/main.cpp @@ -0,0 +1,20 @@ +// +// 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 +// +#include +#include +#include +#include "application.h" + + + +int main(int argc, char* argv[]) +{ + // Instanciate the application... + application app; + + // ... and let it run! + return app.run(argc, argv); +} diff --git a/exercise4/src_solution/src/abstract_curve.cpp b/exercise4/src_solution/src/abstract_curve.cpp new file mode 100644 index 0000000..133c304 --- /dev/null +++ b/exercise4/src_solution/src/abstract_curve.cpp @@ -0,0 +1,74 @@ +// +// 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 +// +#include "abstract_curve.h" + +// Initialize the curve and store a reference of the control points +abstract_curve::abstract_curve(std::vector &control_points): control_points(control_points) +{ + t_min = 0; + t_max = 1; +} + + +abstract_curve::~abstract_curve() {} + +// Evaluate the curve at "t" +point2d abstract_curve::evaluate(double t) +{ + point2d sample(0.0, 0.0); + + for (unsigned int i=0; i& abstract_curve::get_control_points() const +{ + return control_points; +} + + + + +// Shall be called whenever the control point set changes +void abstract_curve::control_points_updated() +{ + // ... does nothing and should be specified in inherited classes + // if needed. +} + + + + +// Put a text into the stream "stream" which will be displayed +// in the main window +void abstract_curve::set_text(std::stringstream &stream) +{ + // ... does nothing and should be specified in inherited classes + // if needed. +} diff --git a/exercise4/src_solution/src/bezier_curve.cpp b/exercise4/src_solution/src/bezier_curve.cpp new file mode 100644 index 0000000..3896ec3 --- /dev/null +++ b/exercise4/src_solution/src/bezier_curve.cpp @@ -0,0 +1,58 @@ +// +// 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 +// +#include "bezier_curve.h" +#include + + +// Initialize the curve and store a reference of the control points +bezier_curve::bezier_curve(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// A helper function to calculate "n choose k" +double bezier_curve::binomial_coefficient(int n, int k) +{ + // Exploit symmetry of pascals triangle + if (k*2>n) + k = n-k; + + if (k<0) + return 0; + + int result = 1; + + // Do not produce too big numbers by dividing + // the result after each step + for (int i=0; i& control_points, int degree): +abstract_curve(control_points) +{ + this->degree = degree; +} + + + + +// The specified "control_points_updated" to adjust the knot vector +// when control points are added or removed +void bspline::control_points_updated() +{ + // Update the knot vector + calculate_knot_vector(); + + // Set the valid range for "t" + if (u.size() != 0) { + t_min = u[0]; + t_max = u[u.size()-1]; + } +} + + + + +// Calculate the knot vector. This method is called from +// "control_points_updated" +void bspline::calculate_knot_vector() +{ + // Initialize variables according to the script + int K = control_points.size(); + int g = degree; + int n = K - g; + + // Clear and resize the knot vector to the right size + u.clear(); + u.resize(K + g + 1); + + for (int i=0; i<=g; i++) + u[i] = 0; + + for (int i=g+1; i<=K; i++) + u[i] = i-g; + + for (int i=K+1; i= get_max_t()) + if (point_num == control_points.size()-1) + return 1.0; + else + return 0.0; + + // Call the recursive version + return evaluate_basis(degree, point_num, 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 bspline::evaluate_basis(int g, int i, double t) +{ + if(g == 0) { + if(t >= u[i] && t < u[i+1]) + return 1.0; + else + return 0.0; + } + + double a = u[i+g] - u[i]; + + if( a != 0) + a = (t-u[i])/a; + + double b = u[i+1+g] - u[i+1]; + + if( b != 0) + b = (u[i+1+g]-t)/b; + + return + a*evaluate_basis(g-1, i, t)+ + b*evaluate_basis(g-1, i+1, t); +} + + + +// Set debug text +void bspline::set_text(std::stringstream &stream) +{ + stream<<"Type: BSpline (with degree "<curve = curve; +} + + + +// Sample the curve using "sample_count" samples and store the +// result in the list "samples". +void curve_renderer::sample_curve(int sample_count) +{ + samples.clear(); + + // Nothing to sample if there are not at least 2 control points + if (curve->get_control_points().size()<2) + return; + + double t=0; + + for (int i=0; i(sample_count-1)*(curve->get_max_t() - curve->get_min_t()); + samples.push_back(curve->evaluate(t)); + } +} + + +// Render the curve +void curve_renderer::render_curve() +{ + int n = samples.size(); + + // Set the color to green + glColor3d(0, 1, 0); + + glBegin(GL_LINE_STRIP); + for (int i=0; iget_max_t(); + if (t_max<=0.0) + t_max = 1.0; + + std::stringstream s; + s<(s.str().c_str())); + + glPopMatrix(); +} + + +// A helper function you can use to set a color for the basis function +void curve_renderer::set_basis_color(int i) +{ + i++; + // Set the color according to the basis function to render + glColor3d(i%2, (i%3)/2.0, (i%5)/6.0); +} + + + +// Render the basis functions +void curve_renderer::render_basis_functions() +{ + double t_max = curve->get_max_t(); + + // Only render the axes if the range is too small + if (t_max <=0.0) { + render_basis_axes(); + return; + } + + // Translate to the lower bottom of the screen and scale + // into the local coordinate system of the basis function graph + glPushMatrix(); + glTranslated(glutGet(GLUT_WINDOW_WIDTH) - basis_width - 10, glutGet(GLUT_WINDOW_HEIGHT) - basis_height - 10, 0); + glScaled(basis_width/t_max, -basis_height, 1); + + // Render the basis functions + for (unsigned int i=0; iget_control_points().size(); i++) { + + glBegin(GL_LINE_STRIP); + + set_basis_color(i); + for (double t = 0; t<=t_max; t+=t_max/100) + glVertex2d(t, curve->evaluate_basis(i, t)); + glEnd(); + } + + glPopMatrix(); + + + // Render the axes + render_basis_axes(); +} \ No newline at end of file diff --git a/exercise4/src_solution/src/hermite_spline.cpp b/exercise4/src_solution/src/hermite_spline.cpp new file mode 100644 index 0000000..f40db7e --- /dev/null +++ b/exercise4/src_solution/src/hermite_spline.cpp @@ -0,0 +1,65 @@ +// +// 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 +// +#include "hermite_spline.h" +#include + + +// Initialize the curve and store a reference of the control points +hermite_spline::hermite_spline(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// Evaluate the curve at "t" +point2d hermite_spline::evaluate(double t) +{ + int n = control_points.size(); + + if (n<3) + return point2d(0.0, 0.0); + + point2d q1 = control_points[0]; + point2d q2 = control_points[n-1]; + point2d m1 = control_points[1] - control_points[0]; + point2d m2 = control_points[n-1] - control_points[n-2]; + + return q1*evaluate_basis(0, t) + + m1*evaluate_basis(1, t) + + m2*evaluate_basis(2, t) + + q2*evaluate_basis(3, t); +} + + + + +// Evaluate a basis as a function of the control point "point_num" +// (counted from zero) and the domain parameter t +double hermite_spline::evaluate_basis(int point_num, double t) +{ + switch (point_num){ + case 0: + return pow(1-t,2)*(1+2*t); + case 1: + return t*pow(1-t,2); + case 2: + return -pow(t,2)*(1-t); + case 3: + return (3-2*t)*pow(t,2); + default: + return 0; + } +} + + + +// Set debug text +void hermite_spline::set_text(std::stringstream &stream) +{ + stream<<"Type: Hermite (simple)"; +} \ No newline at end of file diff --git a/exercise4/src_solution/src/lagrange_curve.cpp b/exercise4/src_solution/src/lagrange_curve.cpp new file mode 100644 index 0000000..c5fcf1c --- /dev/null +++ b/exercise4/src_solution/src/lagrange_curve.cpp @@ -0,0 +1,49 @@ +// +// 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 +// +#include "lagrange_curve.h" + +lagrange_curve::lagrange_curve(std::vector& control_points): abstract_curve(control_points) +{ + +} + + + + +// Called when the control points change. +void lagrange_curve::control_points_updated() +{ + // Update the valid range for "t" according to the + // number of control points + t_max = control_points.size()-1; + if (t_max<0) + t_max = 0; +} + + + + +// Evaluate a basis as a function of the control point "point_num" +// (counted from zero) and the domain parameter t +double lagrange_curve::evaluate_basis(int point_num, double t) +{ + double result = 1.0; + + for (int i=0; i<(int)control_points.size(); i++) + if (i != point_num) + result *= (t - i)/(point_num-i); + + return result; +} + + + + +// Set debug text +void lagrange_curve::set_text(std::stringstream &stream) +{ + stream<<"Type: Lagrange"; +} \ No newline at end of file