<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sascha+willems</id>
		<title>DGL Wiki - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sascha+willems"/>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php/Spezial:Beitr%C3%A4ge/Sascha_willems"/>
		<updated>2026-05-25T03:34:19Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.27.4</generator>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25780</id>
		<title>Vorlage:dglOpenGL History</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25780"/>
				<updated>2013-07-28T18:52:49Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pascal&amp;gt;Version 1.0   - Initial Release&lt;br /&gt;
&lt;br /&gt;
Version 1.1   - Added PPointer in Tpyessection for compatibility with Delphi&lt;br /&gt;
                versions lower than 7                                    (SW)&lt;br /&gt;
              - Added a function named RaiseLastOSError including a comment&lt;br /&gt;
                on how to make it run under Delphi versions lower than 7 (SW)&lt;br /&gt;
              - Added some data types according to the GL-Syntax         (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.2   - Fixed some problems with getting the addresses of some&lt;br /&gt;
                Extensions (e.g. glTexImage3D) where the EXT/ARB did work&lt;br /&gt;
                but not the core-functions                               (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3   - A second call to ReadimplementationProperties won't&lt;br /&gt;
                revert to the default libs anymore                       (MW)&lt;br /&gt;
              - Libraries now will be released if necessary              (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3a  - Small fixes for glSlang-functions                        (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3b  - Fixed a small bug with GL_ARB_shader_objects, that lead&lt;br /&gt;
                lead to that extension not loaded correctly              (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3c  - More GL 1.5 compliance by FOG_COORD_xx and&lt;br /&gt;
                ARB-less VBO and occlusion query routines                (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3d  - Fixed linebreaks (should now be corrected under D5)      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4   - Changed header to correspond to the OpenGL-Shading&lt;br /&gt;
              - Language specification 1.10 :&lt;br /&gt;
                 - Added new GL_SAMPLER_*-Constants&lt;br /&gt;
                 - Added Constant GL_SHADING_LANGUAGE_VERSION_ARB&lt;br /&gt;
                 - Added Constant GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB&lt;br /&gt;
              - Added Constant GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB    (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4a  - Fixed a missing stdcall for glBindAttribLocationARB      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4b  - Fixed declaration for glUniform*(f/i)vARB (added count)  (MW)&lt;br /&gt;
              - glCompileShaderARB changed from function to procedure    (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.5   - Added support for FreePascal                             (BR)&lt;br /&gt;
              - Added type TGLVectorf3/TGLVector3f                       (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.6   - Added Extension GL_EXT_framebuffer_object                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.7   - Added Extension GL_ARB_fragment_program_shadow           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_color_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_pixel                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_float                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_depth_bounds_test                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_mirror_clamp              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_blend_equation_separate           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_dxt1          (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program_option            (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program2                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program2_option             (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program3                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.8   - Added explicit delegate type definitions                 (LM)&lt;br /&gt;
              - Added .Net 1.1 Support                                   (LM)&lt;br /&gt;
              - Added .Net overloaded functions                          (LM)&lt;br /&gt;
              - Added delayed extension loading and stubs                (LM)&lt;br /&gt;
              - Added automatic InitOpenGL call in CreateRenderingContext(LM)&lt;br /&gt;
              - Added extra Read_* function                              (LM)&lt;br /&gt;
&lt;br /&gt;
Version 2.0   - fixed some Problem with version string and damn drivers.&lt;br /&gt;
                String 1.15 identified as OpenGL 1.5 not as OpenGL 1.1   (SX)&lt;br /&gt;
              - Removed unexisting extension GL_ARB_texture_mirror_repeat(SX)&lt;br /&gt;
              - Added Extension WGL_ARB_pixel_format_float               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_stencil_clear_tag                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_edge_clamp                (SX)&lt;br /&gt;
              - Some 1.5 Core Consts added (now completed)               (SX)&lt;br /&gt;
              - gluProject need pointer for not .net                     (SX)&lt;br /&gt;
              - gluUnProject need pointer for not .net                   (SX)&lt;br /&gt;
              - wglUseFontOutlines* need pointer for not .net            (SX)&lt;br /&gt;
              - wglSwapMultipleBuffers need pointer for not .net         (SX)&lt;br /&gt;
              - Bug with wglGetExtensionsStringEXT removed&lt;br /&gt;
                different type for .net                                  (SX)&lt;br /&gt;
              - Added OpenGL 2.0 Core                                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.0.1 - fixed some problems with glGetActiveAttrib in 2.0 Core   (SX)&lt;br /&gt;
              - fixes some problems with gluProject                      (SX)&lt;br /&gt;
              - fixes some problems with gluUnProject                    (SX)&lt;br /&gt;
              - fixes some problems with gluTessVertex                   (SX)&lt;br /&gt;
              - fixes some problems with gluLoadSamplingMatrices         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.1   - Removed .NET Support                                     (SX)&lt;br /&gt;
              - Better support for Linux                                 (SX)&lt;br /&gt;
              - Better Codeformation                                     (SX)&lt;br /&gt;
              - Added some more Vector/Matrix types                      (SX)&lt;br /&gt;
              - Added OpenGL 2.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_depth_stencil              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_blit                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_multisample           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_program_parameters            (SX)&lt;br /&gt;
              - Added Extension GL_EXT_bindable_uniform                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_buffers2                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_shader4                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_float                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_array                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_latc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_integer                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_shared_exponent           (SX)&lt;br /&gt;
              - Added Extension GL_NV_depth_buffer_float                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_framebuffer_multisample_coverage   (SX)&lt;br /&gt;
              - Added Extension GL_NV_geometry_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program4                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object            (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program4                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0   - fixed some consts of GL_EXT_texture_shared_exponent       (SX)&lt;br /&gt;
              - possible better support for mac                          (SX)&lt;br /&gt;
              - Added OpenGL 3.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_object                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_vertex                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_range                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rg                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_object               (SX)&lt;br /&gt;
              - Added Extension GL_NV_conditional_render                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_present_video                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_transform_feedback                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_direct_state_access               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_NV_explicit_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback2                (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension WGL_NV_present_video                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_out                         (SX)&lt;br /&gt;
              - Added Extension WGL_NV_swap_group                        (SX)&lt;br /&gt;
              - Added define DGL_TINY_HEADER to suppress automatic&lt;br /&gt;
                function loading                                         (SX)&lt;br /&gt;
              - glProcedure renamed to dglGetProcAddress and now it's&lt;br /&gt;
                visible from outside the unit to custom load functions   (SX)&lt;br /&gt;
              - dglCheckExtension added to check if an extension exists  (SX)&lt;br /&gt;
              - Read_GL_ARB_buffer_object renamed to&lt;br /&gt;
                Read_GL_ARB_vertex_buffer_object                         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.1 - fixed a problem with fpc                                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.2 - fixed a problem with WGL_ARB_create_context             (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2   - Functions from GL_VERSION_3_0 where updated              (SX)&lt;br /&gt;
              - Functions from GL_ARB_map_buffer_range where updated     (SX)&lt;br /&gt;
              - Functions from GL_NV_present_video where added           (SX)&lt;br /&gt;
              - Added consts of GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Defines to identify Delphi was changed (prevent for          &lt;br /&gt;
                feature maintenance)                                     (SX)&lt;br /&gt;
              - Added Extension GL_ATI_meminfo                           (SX)&lt;br /&gt;
              - Added Extension GL_AMD_performance_monitor               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_texture_texture4                  (SX)&lt;br /&gt;
              - Added Extension GL_AMD_vertex_shader_tesselator          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension WGL_AMD_gpu_association                  (SX)&lt;br /&gt;
              - Added OpenGL 3.1 Core                                    (SX)&lt;br /&gt;
              - All deprecated stuff can be disabled if you undef the        &lt;br /&gt;
                define DGL_DEPRECATED                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_uniform_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_compatibility                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_copy_buffer                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_texture_lod                (SX)&lt;br /&gt;
              - Remove function from GL_NV_present_video                 (SX)&lt;br /&gt;
              - Added Extension WGL_3DL_stereo_control                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_snorm                     (SX)&lt;br /&gt;
              - Added Extension GL_AMD_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_texture_range                   (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_float_pixels                    (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_vertex_program_evaluators       (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_aux_depth_stencil               (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_object_purgeable                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_row_bytes                       (SX)&lt;br /&gt;
              - Added OpenGL 3.2 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_clamp                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_elements_base_vertex         (SX)&lt;br /&gt;
              - Added Extension GL_ARB_fragment_coord_conventions        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_seamless_cube_map                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sync                              (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sample_shading                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_cube_map_array            (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_gather                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_query_lod                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added GLX Core up to Version 1.4                         (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_multisample                      (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_fbconfig_float                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_get_proc_address                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_info                      (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_rating                    (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_import_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_fbconfig_packed_float            (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_texture_from_pixmap              (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.1 - Fixed some problems with Delphi &amp;lt; 6                      (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.2 - Added Extension GL_APPLE_rgb_422                         (SX)&lt;br /&gt;
              - Added Extension GL_EXT_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_NV_video_capture                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_copy_image                         (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object2           (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_load                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_buffer_unified_memory       (SX)&lt;br /&gt;
              - Added Extension GL_NV_texture_barrier                    (SX)&lt;br /&gt;
              - Variable GL_EXT_texture_snorm will be filled             (SX)&lt;br /&gt;
              - Variable GL_APPLE_row_bytes will be filled               (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_capture                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_copy_image                        (SX)&lt;br /&gt;
              - WGL_NV_video_out now named WGL_NV_video_output           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_swap_control                     (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.3 - Fixed a Problem with glGetAttribLocation                (SX)&lt;br /&gt;
              - Added const GL_UNIFORM_BUFFER_EXT                        (SX)&lt;br /&gt;
              - Functions of GL_NV_texture_barrier now will be loaded    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.0   - Changes on Extension GL_ARB_texture_gather               (SX)&lt;br /&gt;
              - Changes on Extension GL_NV_shader_buffer_load            (SX)&lt;br /&gt;
              - Added OpenGL 3.3 Core                                    (SX)&lt;br /&gt;
              - Added OpenGL 4.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_AMD_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_seamless_cubemap_per_texture      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shading_language_include          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_bptc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_blend_func_extended               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_explicit_attrib_location          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_occlusion_query2                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sampler_objects                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_bit_encoding               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rgb10_a2ui                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_type_2_10_10_10_rev        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_indirect                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader5                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader_fp64                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_subroutine                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_tessellation_shader               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object_rgb32       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback2               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback3               (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1   - Possible fix some strange linux behavior                 (SX)&lt;br /&gt;
              - All function uses GL instead of TGL types                (SX)&lt;br /&gt;
              - GL_AMD_vertex_shader_tesselator will be read now         (SX)&lt;br /&gt;
              - GL_AMD_draw_buffers_blend will be read now               (SX)&lt;br /&gt;
              - Changes on glStencilFuncSeparate (GL_2_0)                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_2                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_3                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_4_0                                (SX)&lt;br /&gt;
              - Changes on GL_ARB_sample_shading                         (SX)&lt;br /&gt;
              - Changes on GL_ARB_texture_cube_map_array                 (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader5                            (SX)&lt;br /&gt;
              - Changes on GL_ARB_transform_feedback3                    (SX)&lt;br /&gt;
              - Changes on GL_ARB_sampler_objects                        (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader_fp64                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_element_array                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_vertex_array_range                   (SX)&lt;br /&gt;
              - Changes on GL_NV_transform_feedback                      (SX)&lt;br /&gt;
              - Changes on GL_NV_vertex_buffer_unified_memory            (SX)&lt;br /&gt;
              - Changes on GL_EXT_multi_draw_arrays                      (SX)&lt;br /&gt;
              - Changes on GL_EXT_direct_state_access                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_performance_monitor                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_seamless_cubemap_per_texture           (SX)&lt;br /&gt;
              - Changes on GL_EXT_geometry_shader4                       (SX)&lt;br /&gt;
              - Added OpenGL 4.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_ES2_compatibility                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_get_program_binary                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_precision                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_viewport_array                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_cl_event                          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_robustness                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_conservative_depth                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_shader_image_load_store           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program5                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_shader5                        (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_store                (SX)&lt;br /&gt;
              - Added Extension GL_NV_tessellation_program5              (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_attrib_integer_64bit        (SX)&lt;br /&gt;
              - Added Extension GL_NV_multisample_coverage               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_name_gen_delete                   (SX)&lt;br /&gt;
              - Added Extension GL_AMD_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_vdpau_interop                      (SX)&lt;br /&gt;
              - Added Extension GL_AMD_transform_feedback3_lines_triangles (SX)&lt;br /&gt;
              - Added Extension GL_AMD_depth_clamp_separate              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB_decode               (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension WGL_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
              - Added Extension WGL_NV_multisample_coverage              (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_vertex_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1a  - Fix for dglGetProcAddress with FPC and linux (def param) (SW)&lt;br /&gt;
&lt;br /&gt;
Version 4.2   - Added OpenGL 4.2 Core                                    (SW) &lt;br /&gt;
              - Added Extension GL_ARB_base_instance                     (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_420pack          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback_instanced      (SW) &lt;br /&gt;
              - Added Extension GL_ARB_compressed_texture_pixel_storage  (SW) &lt;br /&gt;
              - Added Extension GL_ARB_conservative_depth                (SW) &lt;br /&gt;
              - Added Extension GL_ARB_internalformat_query              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_alignment              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_atomic_counters            (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_image_load_store           (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_packing          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_texture_storage                   (SW) &lt;br /&gt;
              - Added Extension WGL_NV_DX_interop                        (SW) &lt;br /&gt;
              - Added Define for WGL_EXT_create_context_es2_profile      (SW) &lt;br /&gt;
&lt;br /&gt;
Version 4.2a  - Added Mac OS X patch by Andrey Gruzdev                   (SW) &lt;br /&gt;
&lt;br /&gt;
 Version 4.3    Added OpenGL 4.3 Core                                    (SW)&lt;br /&gt;
  		Added GL_ARB_arrays_of_arrays		                 (SW)&lt;br /&gt;
  		Added GL_ARB_fragment_layer_viewport                     (SW)&lt;br /&gt;
  		Added GL_ARB_shader_image_size                           (SW)&lt;br /&gt;
  		Added GL_ARB_ES3_compatibility                           (SW)&lt;br /&gt;
  		Added GL_ARB_clear_buffer_object                         (SW)&lt;br /&gt;
  		Added GL_ARB_compute_shader                              (SW)&lt;br /&gt;
  		Added GL_ARB_copy_image                                  (SW)&lt;br /&gt;
  		Added GL_KHR_debug                                       (SW)&lt;br /&gt;
  		Added GL_ARB_explicit_uniform_location,                  (SW)&lt;br /&gt;
  		Added GL_ARB_framebuffer_no_attachments                  (SW)&lt;br /&gt;
  		Added GL_ARB_internalformat_query2                       (SW)&lt;br /&gt;
  		Added GL_ARB_invalidate_subdata                          (SW)&lt;br /&gt;
  		Added GL_ARB_multi_draw_indirect                         (SW)&lt;br /&gt;
  		Added GL_ARB_program_interface_query                     (SW)&lt;br /&gt;
  		Added GL_ARB_robust_buffer_access_behavior               (SW)&lt;br /&gt;
  		Added GL_ARB_shader_storage_buffer_object                (SW)&lt;br /&gt;
  		Added GL_ARB_stencil_texturing                           (SW)&lt;br /&gt;
  		Added GL_ARB_texture_buffer_range                        (SW)&lt;br /&gt;
  		Added GL_ARB_texture_query_levels                        (SW)&lt;br /&gt;
  		Added GL_ARB_texture_storage_multisample                 (SW)&lt;br /&gt;
  		Added GL_ARB_texture_view                                (SW)&lt;br /&gt;
  		Added GL_ARB_vertex_attrib_binding                       (SW)&lt;br /&gt;
                Added new vendor-specific extensions			 (SW)&lt;br /&gt;
		Added GL_NV_path_rendering                               (SW)&lt;br /&gt;
  		Added GL_AMD_pinned_memory                               (SW)&lt;br /&gt;
                Added GL_AMD_stencil_operation_extended                  (SW)&lt;br /&gt;
                Added GL_AMD_vertex_shader_viewport_index                (SW)&lt;br /&gt;
                Added GL_AMD_vertex_shader_layer                         (SW)&lt;br /&gt;
                Added GL_NV_bindless_texture                             (SW)&lt;br /&gt;
                Added GL_NV_shader_atomic_float                          (SW)&lt;br /&gt;
                Added GL_AMD_query_buffer_object                         (SW)&lt;br /&gt;
                Added CreateRenderingContextVersion                      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 4.4     Added ARB_buffer_storage                                 (SW)&lt;br /&gt;
                Added ARB_clear_texture extension                        (SW)&lt;br /&gt;
                Added ARB_enhanced_layouts extension                     (SW)&lt;br /&gt;
                Added ARB_multi_bind extension                           (SW)&lt;br /&gt;
                Added ARB_query_buffer_object extension                  (SW)&lt;br /&gt;
                Added ARB_texture_mirror_clamp_to_edge extension         (SW)&lt;br /&gt;
                Added ARB_texture_stencil8 extension                     (SW)&lt;br /&gt;
                Added ARB_vertex_type_10f_11f_11f_rev extension          (SW)&lt;br /&gt;
                Added MAX_VERTEX_ATTRIB_STRIDE stat                      (SW)&lt;br /&gt;
                Added missing functions for GL_EXT_direct_state_access   (SW)&lt;br /&gt;
                GL3.0+ uses non-deprecated way of getting extensions&lt;br /&gt;
                (thanks to frenK)  					 (SW)&lt;br /&gt;
                Added missing cdecl for TglXGetVisualFromFBConfig        (SW)&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25779</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25779"/>
				<updated>2013-07-28T18:50:39Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* The DelphiGL header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
To compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easy (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 4.4) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extension that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check whether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}}'''&lt;br /&gt;
&lt;br /&gt;
(Supports ''OpenGL 4.4'', works with Delphi 4 and up and Freepascal))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')''&lt;br /&gt;
&lt;br /&gt;
''(Note : This header is'nt developed any further)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25692</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25692"/>
				<updated>2012-08-08T16:48:36Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
To compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easy (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 4.2) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extension that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check whether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}}'''&lt;br /&gt;
&lt;br /&gt;
(Supports ''OpenGL 4.3'', works with Delphi 4 and up and Freepascal))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')''&lt;br /&gt;
&lt;br /&gt;
''(Note : This header is'nt developed any further)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25691</id>
		<title>Vorlage:dglOpenGL History</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25691"/>
				<updated>2012-08-08T16:47:04Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pascal&amp;gt;Version 1.0   - Initial Release&lt;br /&gt;
&lt;br /&gt;
Version 1.1   - Added PPointer in Tpyessection for compatibility with Delphi&lt;br /&gt;
                versions lower than 7                                    (SW)&lt;br /&gt;
              - Added a function named RaiseLastOSError including a comment&lt;br /&gt;
                on how to make it run under Delphi versions lower than 7 (SW)&lt;br /&gt;
              - Added some data types according to the GL-Syntax         (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.2   - Fixed some problems with getting the addresses of some&lt;br /&gt;
                Extensions (e.g. glTexImage3D) where the EXT/ARB did work&lt;br /&gt;
                but not the core-functions                               (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3   - A second call to ReadimplementationProperties won't&lt;br /&gt;
                revert to the default libs anymore                       (MW)&lt;br /&gt;
              - Libraries now will be released if necessary              (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3a  - Small fixes for glSlang-functions                        (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3b  - Fixed a small bug with GL_ARB_shader_objects, that lead&lt;br /&gt;
                lead to that extension not loaded correctly              (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3c  - More GL 1.5 compliance by FOG_COORD_xx and&lt;br /&gt;
                ARB-less VBO and occlusion query routines                (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3d  - Fixed linebreaks (should now be corrected under D5)      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4   - Changed header to correspond to the OpenGL-Shading&lt;br /&gt;
              - Language specification 1.10 :&lt;br /&gt;
                 - Added new GL_SAMPLER_*-Constants&lt;br /&gt;
                 - Added Constant GL_SHADING_LANGUAGE_VERSION_ARB&lt;br /&gt;
                 - Added Constant GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB&lt;br /&gt;
              - Added Constant GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB    (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4a  - Fixed a missing stdcall for glBindAttribLocationARB      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4b  - Fixed declaration for glUniform*(f/i)vARB (added count)  (MW)&lt;br /&gt;
              - glCompileShaderARB changed from function to procedure    (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.5   - Added support for FreePascal                             (BR)&lt;br /&gt;
              - Added type TGLVectorf3/TGLVector3f                       (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.6   - Added Extension GL_EXT_framebuffer_object                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.7   - Added Extension GL_ARB_fragment_program_shadow           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_color_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_pixel                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_float                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_depth_bounds_test                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_mirror_clamp              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_blend_equation_separate           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_dxt1          (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program_option            (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program2                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program2_option             (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program3                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.8   - Added explicit delegate type definitions                 (LM)&lt;br /&gt;
              - Added .Net 1.1 Support                                   (LM)&lt;br /&gt;
              - Added .Net overloaded functions                          (LM)&lt;br /&gt;
              - Added delayed extension loading and stubs                (LM)&lt;br /&gt;
              - Added automatic InitOpenGL call in CreateRenderingContext(LM)&lt;br /&gt;
              - Added extra Read_* function                              (LM)&lt;br /&gt;
&lt;br /&gt;
Version 2.0   - fixed some Problem with version string and damn drivers.&lt;br /&gt;
                String 1.15 identified as OpenGL 1.5 not as OpenGL 1.1   (SX)&lt;br /&gt;
              - Removed unexisting extension GL_ARB_texture_mirror_repeat(SX)&lt;br /&gt;
              - Added Extension WGL_ARB_pixel_format_float               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_stencil_clear_tag                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_edge_clamp                (SX)&lt;br /&gt;
              - Some 1.5 Core Consts added (now completed)               (SX)&lt;br /&gt;
              - gluProject need pointer for not .net                     (SX)&lt;br /&gt;
              - gluUnProject need pointer for not .net                   (SX)&lt;br /&gt;
              - wglUseFontOutlines* need pointer for not .net            (SX)&lt;br /&gt;
              - wglSwapMultipleBuffers need pointer for not .net         (SX)&lt;br /&gt;
              - Bug with wglGetExtensionsStringEXT removed&lt;br /&gt;
                different type for .net                                  (SX)&lt;br /&gt;
              - Added OpenGL 2.0 Core                                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.0.1 - fixed some problems with glGetActiveAttrib in 2.0 Core   (SX)&lt;br /&gt;
              - fixes some problems with gluProject                      (SX)&lt;br /&gt;
              - fixes some problems with gluUnProject                    (SX)&lt;br /&gt;
              - fixes some problems with gluTessVertex                   (SX)&lt;br /&gt;
              - fixes some problems with gluLoadSamplingMatrices         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.1   - Removed .NET Support                                     (SX)&lt;br /&gt;
              - Better support for Linux                                 (SX)&lt;br /&gt;
              - Better Codeformation                                     (SX)&lt;br /&gt;
              - Added some more Vector/Matrix types                      (SX)&lt;br /&gt;
              - Added OpenGL 2.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_depth_stencil              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_blit                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_multisample           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_program_parameters            (SX)&lt;br /&gt;
              - Added Extension GL_EXT_bindable_uniform                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_buffers2                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_shader4                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_float                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_array                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_latc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_integer                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_shared_exponent           (SX)&lt;br /&gt;
              - Added Extension GL_NV_depth_buffer_float                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_framebuffer_multisample_coverage   (SX)&lt;br /&gt;
              - Added Extension GL_NV_geometry_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program4                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object            (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program4                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0   - fixed some consts of GL_EXT_texture_shared_exponent       (SX)&lt;br /&gt;
              - possible better support for mac                          (SX)&lt;br /&gt;
              - Added OpenGL 3.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_object                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_vertex                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_range                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rg                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_object               (SX)&lt;br /&gt;
              - Added Extension GL_NV_conditional_render                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_present_video                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_transform_feedback                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_direct_state_access               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_NV_explicit_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback2                (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension WGL_NV_present_video                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_out                         (SX)&lt;br /&gt;
              - Added Extension WGL_NV_swap_group                        (SX)&lt;br /&gt;
              - Added define DGL_TINY_HEADER to suppress automatic&lt;br /&gt;
                function loading                                         (SX)&lt;br /&gt;
              - glProcedure renamed to dglGetProcAddress and now it's&lt;br /&gt;
                visible from outside the unit to custom load functions   (SX)&lt;br /&gt;
              - dglCheckExtension added to check if an extension exists  (SX)&lt;br /&gt;
              - Read_GL_ARB_buffer_object renamed to&lt;br /&gt;
                Read_GL_ARB_vertex_buffer_object                         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.1 - fixed a problem with fpc                                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.2 - fixed a problem with WGL_ARB_create_context             (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2   - Functions from GL_VERSION_3_0 where updated              (SX)&lt;br /&gt;
              - Functions from GL_ARB_map_buffer_range where updated     (SX)&lt;br /&gt;
              - Functions from GL_NV_present_video where added           (SX)&lt;br /&gt;
              - Added consts of GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Defines to identify Delphi was changed (prevent for          &lt;br /&gt;
                feature maintenance)                                     (SX)&lt;br /&gt;
              - Added Extension GL_ATI_meminfo                           (SX)&lt;br /&gt;
              - Added Extension GL_AMD_performance_monitor               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_texture_texture4                  (SX)&lt;br /&gt;
              - Added Extension GL_AMD_vertex_shader_tesselator          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension WGL_AMD_gpu_association                  (SX)&lt;br /&gt;
              - Added OpenGL 3.1 Core                                    (SX)&lt;br /&gt;
              - All deprecated stuff can be disabled if you undef the        &lt;br /&gt;
                define DGL_DEPRECATED                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_uniform_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_compatibility                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_copy_buffer                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_texture_lod                (SX)&lt;br /&gt;
              - Remove function from GL_NV_present_video                 (SX)&lt;br /&gt;
              - Added Extension WGL_3DL_stereo_control                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_snorm                     (SX)&lt;br /&gt;
              - Added Extension GL_AMD_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_texture_range                   (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_float_pixels                    (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_vertex_program_evaluators       (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_aux_depth_stencil               (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_object_purgeable                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_row_bytes                       (SX)&lt;br /&gt;
              - Added OpenGL 3.2 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_clamp                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_elements_base_vertex         (SX)&lt;br /&gt;
              - Added Extension GL_ARB_fragment_coord_conventions        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_seamless_cube_map                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sync                              (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sample_shading                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_cube_map_array            (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_gather                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_query_lod                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added GLX Core up to Version 1.4                         (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_multisample                      (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_fbconfig_float                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_get_proc_address                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_info                      (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_rating                    (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_import_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_fbconfig_packed_float            (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_texture_from_pixmap              (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.1 - Fixed some problems with Delphi &amp;lt; 6                      (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.2 - Added Extension GL_APPLE_rgb_422                         (SX)&lt;br /&gt;
              - Added Extension GL_EXT_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_NV_video_capture                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_copy_image                         (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object2           (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_load                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_buffer_unified_memory       (SX)&lt;br /&gt;
              - Added Extension GL_NV_texture_barrier                    (SX)&lt;br /&gt;
              - Variable GL_EXT_texture_snorm will be filled             (SX)&lt;br /&gt;
              - Variable GL_APPLE_row_bytes will be filled               (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_capture                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_copy_image                        (SX)&lt;br /&gt;
              - WGL_NV_video_out now named WGL_NV_video_output           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_swap_control                     (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.3 - Fixed a Problem with glGetAttribLocation                (SX)&lt;br /&gt;
              - Added const GL_UNIFORM_BUFFER_EXT                        (SX)&lt;br /&gt;
              - Functions of GL_NV_texture_barrier now will be loaded    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.0   - Changes on Extension GL_ARB_texture_gather               (SX)&lt;br /&gt;
              - Changes on Extension GL_NV_shader_buffer_load            (SX)&lt;br /&gt;
              - Added OpenGL 3.3 Core                                    (SX)&lt;br /&gt;
              - Added OpenGL 4.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_AMD_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_seamless_cubemap_per_texture      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shading_language_include          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_bptc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_blend_func_extended               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_explicit_attrib_location          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_occlusion_query2                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sampler_objects                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_bit_encoding               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rgb10_a2ui                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_type_2_10_10_10_rev        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_indirect                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader5                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader_fp64                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_subroutine                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_tessellation_shader               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object_rgb32       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback2               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback3               (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1   - Possible fix some strange linux behavior                 (SX)&lt;br /&gt;
              - All function uses GL instead of TGL types                (SX)&lt;br /&gt;
              - GL_AMD_vertex_shader_tesselator will be read now         (SX)&lt;br /&gt;
              - GL_AMD_draw_buffers_blend will be read now               (SX)&lt;br /&gt;
              - Changes on glStencilFuncSeparate (GL_2_0)                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_2                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_3                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_4_0                                (SX)&lt;br /&gt;
              - Changes on GL_ARB_sample_shading                         (SX)&lt;br /&gt;
              - Changes on GL_ARB_texture_cube_map_array                 (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader5                            (SX)&lt;br /&gt;
              - Changes on GL_ARB_transform_feedback3                    (SX)&lt;br /&gt;
              - Changes on GL_ARB_sampler_objects                        (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader_fp64                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_element_array                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_vertex_array_range                   (SX)&lt;br /&gt;
              - Changes on GL_NV_transform_feedback                      (SX)&lt;br /&gt;
              - Changes on GL_NV_vertex_buffer_unified_memory            (SX)&lt;br /&gt;
              - Changes on GL_EXT_multi_draw_arrays                      (SX)&lt;br /&gt;
              - Changes on GL_EXT_direct_state_access                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_performance_monitor                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_seamless_cubemap_per_texture           (SX)&lt;br /&gt;
              - Changes on GL_EXT_geometry_shader4                       (SX)&lt;br /&gt;
              - Added OpenGL 4.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_ES2_compatibility                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_get_program_binary                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_precision                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_viewport_array                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_cl_event                          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_robustness                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_conservative_depth                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_shader_image_load_store           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program5                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_shader5                        (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_store                (SX)&lt;br /&gt;
              - Added Extension GL_NV_tessellation_program5              (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_attrib_integer_64bit        (SX)&lt;br /&gt;
              - Added Extension GL_NV_multisample_coverage               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_name_gen_delete                   (SX)&lt;br /&gt;
              - Added Extension GL_AMD_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_vdpau_interop                      (SX)&lt;br /&gt;
              - Added Extension GL_AMD_transform_feedback3_lines_triangles (SX)&lt;br /&gt;
              - Added Extension GL_AMD_depth_clamp_separate              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB_decode               (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension WGL_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
              - Added Extension WGL_NV_multisample_coverage              (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_vertex_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1a  - Fix for dglGetProcAddress with FPC and linux (def param) (SW)&lt;br /&gt;
&lt;br /&gt;
Version 4.2   - Added OpenGL 4.2 Core                                    (SW) &lt;br /&gt;
              - Added Extension GL_ARB_base_instance                     (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_420pack          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback_instanced      (SW) &lt;br /&gt;
              - Added Extension GL_ARB_compressed_texture_pixel_storage  (SW) &lt;br /&gt;
              - Added Extension GL_ARB_conservative_depth                (SW) &lt;br /&gt;
              - Added Extension GL_ARB_internalformat_query              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_alignment              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_atomic_counters            (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_image_load_store           (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_packing          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_texture_storage                   (SW) &lt;br /&gt;
              - Added Extension WGL_NV_DX_interop                        (SW) &lt;br /&gt;
              - Added Define for WGL_EXT_create_context_es2_profile      (SW) &lt;br /&gt;
&lt;br /&gt;
Version 4.2a  - Added Mac OS X patch by Andrey Gruzdev                   (SW) &lt;br /&gt;
&lt;br /&gt;
 Version 4.3    Added OpenGL 4.3 Core                                    (SW)&lt;br /&gt;
  		Added GL_ARB_arrays_of_arrays		                 (SW)&lt;br /&gt;
  		Added GL_ARB_fragment_layer_viewport                     (SW)&lt;br /&gt;
  		Added GL_ARB_shader_image_size                           (SW)&lt;br /&gt;
  		Added GL_ARB_ES3_compatibility                           (SW)&lt;br /&gt;
  		Added GL_ARB_clear_buffer_object                         (SW)&lt;br /&gt;
  		Added GL_ARB_compute_shader                              (SW)&lt;br /&gt;
  		Added GL_ARB_copy_image                                  (SW)&lt;br /&gt;
  		Added GL_KHR_debug                                       (SW)&lt;br /&gt;
  		Added GL_ARB_explicit_uniform_location,                  (SW)&lt;br /&gt;
  		Added GL_ARB_framebuffer_no_attachments                  (SW)&lt;br /&gt;
  		Added GL_ARB_internalformat_query2                       (SW)&lt;br /&gt;
  		Added GL_ARB_invalidate_subdata                          (SW)&lt;br /&gt;
  		Added GL_ARB_multi_draw_indirect                         (SW)&lt;br /&gt;
  		Added GL_ARB_program_interface_query                     (SW)&lt;br /&gt;
  		Added GL_ARB_robust_buffer_access_behavior               (SW)&lt;br /&gt;
  		Added GL_ARB_shader_storage_buffer_object                (SW)&lt;br /&gt;
  		Added GL_ARB_stencil_texturing                           (SW)&lt;br /&gt;
  		Added GL_ARB_texture_buffer_range                        (SW)&lt;br /&gt;
  		Added GL_ARB_texture_query_levels                        (SW)&lt;br /&gt;
  		Added GL_ARB_texture_storage_multisample                 (SW)&lt;br /&gt;
  		Added GL_ARB_texture_view                                (SW)&lt;br /&gt;
  		Added GL_ARB_vertex_attrib_binding                       (SW)&lt;br /&gt;
                Added new vendor-specific extensions			 (SW)&lt;br /&gt;
		Added GL_NV_path_rendering                               (SW)&lt;br /&gt;
  		Added GL_AMD_pinned_memory                               (SW)&lt;br /&gt;
                Added GL_AMD_stencil_operation_extended                  (SW)&lt;br /&gt;
                Added GL_AMD_vertex_shader_viewport_index                (SW)&lt;br /&gt;
                Added GL_AMD_vertex_shader_layer                         (SW)&lt;br /&gt;
                Added GL_NV_bindless_texture                             (SW)&lt;br /&gt;
                Added GL_NV_shader_atomic_float                          (SW)&lt;br /&gt;
                Added GL_AMD_query_buffer_object                         (SW)&lt;br /&gt;
                Added CreateRenderingContextVersion                      (SW)&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25432</id>
		<title>Vorlage:dglOpenGL History</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25432"/>
				<updated>2011-11-26T10:55:32Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: 4.2a&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pascal&amp;gt;Version 1.0   - Initial Release&lt;br /&gt;
&lt;br /&gt;
Version 1.1   - Added PPointer in Tpyessection for compatibility with Delphi&lt;br /&gt;
                versions lower than 7                                    (SW)&lt;br /&gt;
              - Added a function named RaiseLastOSError including a comment&lt;br /&gt;
                on how to make it run under Delphi versions lower than 7 (SW)&lt;br /&gt;
              - Added some data types according to the GL-Syntax         (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.2   - Fixed some problems with getting the addresses of some&lt;br /&gt;
                Extensions (e.g. glTexImage3D) where the EXT/ARB did work&lt;br /&gt;
                but not the core-functions                               (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3   - A second call to ReadimplementationProperties won't&lt;br /&gt;
                revert to the default libs anymore                       (MW)&lt;br /&gt;
              - Libraries now will be released if necessary              (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3a  - Small fixes for glSlang-functions                        (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3b  - Fixed a small bug with GL_ARB_shader_objects, that lead&lt;br /&gt;
                lead to that extension not loaded correctly              (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3c  - More GL 1.5 compliance by FOG_COORD_xx and&lt;br /&gt;
                ARB-less VBO and occlusion query routines                (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3d  - Fixed linebreaks (should now be corrected under D5)      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4   - Changed header to correspond to the OpenGL-Shading&lt;br /&gt;
              - Language specification 1.10 :&lt;br /&gt;
                 - Added new GL_SAMPLER_*-Constants&lt;br /&gt;
                 - Added Constant GL_SHADING_LANGUAGE_VERSION_ARB&lt;br /&gt;
                 - Added Constant GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB&lt;br /&gt;
              - Added Constant GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB    (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4a  - Fixed a missing stdcall for glBindAttribLocationARB      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4b  - Fixed declaration for glUniform*(f/i)vARB (added count)  (MW)&lt;br /&gt;
              - glCompileShaderARB changed from function to procedure    (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.5   - Added support for FreePascal                             (BR)&lt;br /&gt;
              - Added type TGLVectorf3/TGLVector3f                       (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.6   - Added Extension GL_EXT_framebuffer_object                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.7   - Added Extension GL_ARB_fragment_program_shadow           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_color_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_pixel                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_float                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_depth_bounds_test                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_mirror_clamp              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_blend_equation_separate           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_dxt1          (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program_option            (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program2                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program2_option             (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program3                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.8   - Added explicit delegate type definitions                 (LM)&lt;br /&gt;
              - Added .Net 1.1 Support                                   (LM)&lt;br /&gt;
              - Added .Net overloaded functions                          (LM)&lt;br /&gt;
              - Added delayed extension loading and stubs                (LM)&lt;br /&gt;
              - Added automatic InitOpenGL call in CreateRenderingContext(LM)&lt;br /&gt;
              - Added extra Read_* function                              (LM)&lt;br /&gt;
&lt;br /&gt;
Version 2.0   - fixed some Problem with version string and damn drivers.&lt;br /&gt;
                String 1.15 identified as OpenGL 1.5 not as OpenGL 1.1   (SX)&lt;br /&gt;
              - Removed unexisting extension GL_ARB_texture_mirror_repeat(SX)&lt;br /&gt;
              - Added Extension WGL_ARB_pixel_format_float               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_stencil_clear_tag                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_edge_clamp                (SX)&lt;br /&gt;
              - Some 1.5 Core Consts added (now completed)               (SX)&lt;br /&gt;
              - gluProject need pointer for not .net                     (SX)&lt;br /&gt;
              - gluUnProject need pointer for not .net                   (SX)&lt;br /&gt;
              - wglUseFontOutlines* need pointer for not .net            (SX)&lt;br /&gt;
              - wglSwapMultipleBuffers need pointer for not .net         (SX)&lt;br /&gt;
              - Bug with wglGetExtensionsStringEXT removed&lt;br /&gt;
                different type for .net                                  (SX)&lt;br /&gt;
              - Added OpenGL 2.0 Core                                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.0.1 - fixed some problems with glGetActiveAttrib in 2.0 Core   (SX)&lt;br /&gt;
              - fixes some problems with gluProject                      (SX)&lt;br /&gt;
              - fixes some problems with gluUnProject                    (SX)&lt;br /&gt;
              - fixes some problems with gluTessVertex                   (SX)&lt;br /&gt;
              - fixes some problems with gluLoadSamplingMatrices         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.1   - Removed .NET Support                                     (SX)&lt;br /&gt;
              - Better support for Linux                                 (SX)&lt;br /&gt;
              - Better Codeformation                                     (SX)&lt;br /&gt;
              - Added some more Vector/Matrix types                      (SX)&lt;br /&gt;
              - Added OpenGL 2.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_depth_stencil              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_blit                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_multisample           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_program_parameters            (SX)&lt;br /&gt;
              - Added Extension GL_EXT_bindable_uniform                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_buffers2                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_shader4                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_float                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_array                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_latc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_integer                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_shared_exponent           (SX)&lt;br /&gt;
              - Added Extension GL_NV_depth_buffer_float                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_framebuffer_multisample_coverage   (SX)&lt;br /&gt;
              - Added Extension GL_NV_geometry_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program4                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object            (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program4                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0   - fixed some consts of GL_EXT_texture_shared_exponent       (SX)&lt;br /&gt;
              - possible better support for mac                          (SX)&lt;br /&gt;
              - Added OpenGL 3.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_object                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_vertex                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_range                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rg                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_object               (SX)&lt;br /&gt;
              - Added Extension GL_NV_conditional_render                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_present_video                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_transform_feedback                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_direct_state_access               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_NV_explicit_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback2                (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension WGL_NV_present_video                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_out                         (SX)&lt;br /&gt;
              - Added Extension WGL_NV_swap_group                        (SX)&lt;br /&gt;
              - Added define DGL_TINY_HEADER to suppress automatic&lt;br /&gt;
                function loading                                         (SX)&lt;br /&gt;
              - glProcedure renamed to dglGetProcAddress and now it's&lt;br /&gt;
                visible from outside the unit to custom load functions   (SX)&lt;br /&gt;
              - dglCheckExtension added to check if an extension exists  (SX)&lt;br /&gt;
              - Read_GL_ARB_buffer_object renamed to&lt;br /&gt;
                Read_GL_ARB_vertex_buffer_object                         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.1 - fixed a problem with fpc                                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.2 - fixed a problem with WGL_ARB_create_context             (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2   - Functions from GL_VERSION_3_0 where updated              (SX)&lt;br /&gt;
              - Functions from GL_ARB_map_buffer_range where updated     (SX)&lt;br /&gt;
              - Functions from GL_NV_present_video where added           (SX)&lt;br /&gt;
              - Added consts of GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Defines to identify Delphi was changed (prevent for          &lt;br /&gt;
                feature maintenance)                                     (SX)&lt;br /&gt;
              - Added Extension GL_ATI_meminfo                           (SX)&lt;br /&gt;
              - Added Extension GL_AMD_performance_monitor               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_texture_texture4                  (SX)&lt;br /&gt;
              - Added Extension GL_AMD_vertex_shader_tesselator          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension WGL_AMD_gpu_association                  (SX)&lt;br /&gt;
              - Added OpenGL 3.1 Core                                    (SX)&lt;br /&gt;
              - All deprecated stuff can be disabled if you undef the        &lt;br /&gt;
                define DGL_DEPRECATED                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_uniform_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_compatibility                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_copy_buffer                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_texture_lod                (SX)&lt;br /&gt;
              - Remove function from GL_NV_present_video                 (SX)&lt;br /&gt;
              - Added Extension WGL_3DL_stereo_control                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_snorm                     (SX)&lt;br /&gt;
              - Added Extension GL_AMD_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_texture_range                   (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_float_pixels                    (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_vertex_program_evaluators       (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_aux_depth_stencil               (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_object_purgeable                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_row_bytes                       (SX)&lt;br /&gt;
              - Added OpenGL 3.2 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_clamp                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_elements_base_vertex         (SX)&lt;br /&gt;
              - Added Extension GL_ARB_fragment_coord_conventions        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_seamless_cube_map                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sync                              (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sample_shading                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_cube_map_array            (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_gather                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_query_lod                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added GLX Core up to Version 1.4                         (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_multisample                      (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_fbconfig_float                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_get_proc_address                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_info                      (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_rating                    (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_import_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_fbconfig_packed_float            (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_texture_from_pixmap              (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.1 - Fixed some problems with Delphi &amp;lt; 6                      (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.2 - Added Extension GL_APPLE_rgb_422                         (SX)&lt;br /&gt;
              - Added Extension GL_EXT_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_NV_video_capture                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_copy_image                         (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object2           (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_load                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_buffer_unified_memory       (SX)&lt;br /&gt;
              - Added Extension GL_NV_texture_barrier                    (SX)&lt;br /&gt;
              - Variable GL_EXT_texture_snorm will be filled             (SX)&lt;br /&gt;
              - Variable GL_APPLE_row_bytes will be filled               (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_capture                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_copy_image                        (SX)&lt;br /&gt;
              - WGL_NV_video_out now named WGL_NV_video_output           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_swap_control                     (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.3 - Fixed a Problem with glGetAttribLocation                (SX)&lt;br /&gt;
              - Added const GL_UNIFORM_BUFFER_EXT                        (SX)&lt;br /&gt;
              - Functions of GL_NV_texture_barrier now will be loaded    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.0   - Changes on Extension GL_ARB_texture_gather               (SX)&lt;br /&gt;
              - Changes on Extension GL_NV_shader_buffer_load            (SX)&lt;br /&gt;
              - Added OpenGL 3.3 Core                                    (SX)&lt;br /&gt;
              - Added OpenGL 4.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_AMD_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_seamless_cubemap_per_texture      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shading_language_include          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_bptc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_blend_func_extended               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_explicit_attrib_location          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_occlusion_query2                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sampler_objects                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_bit_encoding               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rgb10_a2ui                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_type_2_10_10_10_rev        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_indirect                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader5                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader_fp64                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_subroutine                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_tessellation_shader               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object_rgb32       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback2               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback3               (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1   - Possible fix some strange linux behavior                 (SX)&lt;br /&gt;
              - All function uses GL instead of TGL types                (SX)&lt;br /&gt;
              - GL_AMD_vertex_shader_tesselator will be read now         (SX)&lt;br /&gt;
              - GL_AMD_draw_buffers_blend will be read now               (SX)&lt;br /&gt;
              - Changes on glStencilFuncSeparate (GL_2_0)                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_2                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_3                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_4_0                                (SX)&lt;br /&gt;
              - Changes on GL_ARB_sample_shading                         (SX)&lt;br /&gt;
              - Changes on GL_ARB_texture_cube_map_array                 (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader5                            (SX)&lt;br /&gt;
              - Changes on GL_ARB_transform_feedback3                    (SX)&lt;br /&gt;
              - Changes on GL_ARB_sampler_objects                        (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader_fp64                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_element_array                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_vertex_array_range                   (SX)&lt;br /&gt;
              - Changes on GL_NV_transform_feedback                      (SX)&lt;br /&gt;
              - Changes on GL_NV_vertex_buffer_unified_memory            (SX)&lt;br /&gt;
              - Changes on GL_EXT_multi_draw_arrays                      (SX)&lt;br /&gt;
              - Changes on GL_EXT_direct_state_access                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_performance_monitor                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_seamless_cubemap_per_texture           (SX)&lt;br /&gt;
              - Changes on GL_EXT_geometry_shader4                       (SX)&lt;br /&gt;
              - Added OpenGL 4.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_ES2_compatibility                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_get_program_binary                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_precision                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_viewport_array                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_cl_event                          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_robustness                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_conservative_depth                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_shader_image_load_store           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program5                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_shader5                        (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_store                (SX)&lt;br /&gt;
              - Added Extension GL_NV_tessellation_program5              (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_attrib_integer_64bit        (SX)&lt;br /&gt;
              - Added Extension GL_NV_multisample_coverage               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_name_gen_delete                   (SX)&lt;br /&gt;
              - Added Extension GL_AMD_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_vdpau_interop                      (SX)&lt;br /&gt;
              - Added Extension GL_AMD_transform_feedback3_lines_triangles (SX)&lt;br /&gt;
              - Added Extension GL_AMD_depth_clamp_separate              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB_decode               (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension WGL_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
              - Added Extension WGL_NV_multisample_coverage              (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_vertex_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1a  - Fix for dglGetProcAddress with FPC and linux (def param) (SW)&lt;br /&gt;
&lt;br /&gt;
Version 4.2   - Added OpenGL 4.2 Core                                    (SW) &lt;br /&gt;
              - Added Extension GL_ARB_base_instance                     (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_420pack          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback_instanced      (SW) &lt;br /&gt;
              - Added Extension GL_ARB_compressed_texture_pixel_storage  (SW) &lt;br /&gt;
              - Added Extension GL_ARB_conservative_depth                (SW) &lt;br /&gt;
              - Added Extension GL_ARB_internalformat_query              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_alignment              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_atomic_counters            (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_image_load_store           (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_packing          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_texture_storage                   (SW) &lt;br /&gt;
              - Added Extension WGL_NV_DX_interop                        (SW) &lt;br /&gt;
              - Added Define for WGL_EXT_create_context_es2_profile      (SW) &lt;br /&gt;
&lt;br /&gt;
Version 4.2a  - Added Mac OS X patch by Andrey Gruzdev                   (SW) &lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25333</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25333"/>
				<updated>2011-08-08T20:13:06Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Download */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
To compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easy (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 4.2) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extension that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check whether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}}'''&lt;br /&gt;
&lt;br /&gt;
(Supports ''OpenGL 4.2'', works with Delphi 4 and up and Freepascal))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')''&lt;br /&gt;
&lt;br /&gt;
''(Note : This header is'nt developed any further)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25332</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25332"/>
				<updated>2011-08-08T20:12:50Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* The DelphiGL header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
To compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easy (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 4.2) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extension that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check whether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}}'''&lt;br /&gt;
&lt;br /&gt;
(Supports ''OpenGL 4.1'', works with Delphi 4 and up and Freepascal))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')''&lt;br /&gt;
&lt;br /&gt;
''(Note : This header is'nt developed any further)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25331</id>
		<title>Vorlage:dglOpenGL History</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25331"/>
				<updated>2011-08-08T20:05:10Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Version 4.2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pascal&amp;gt;Version 1.0   - Initial Release&lt;br /&gt;
&lt;br /&gt;
Version 1.1   - Added PPointer in Tpyessection for compatibility with Delphi&lt;br /&gt;
                versions lower than 7                                    (SW)&lt;br /&gt;
              - Added a function named RaiseLastOSError including a comment&lt;br /&gt;
                on how to make it run under Delphi versions lower than 7 (SW)&lt;br /&gt;
              - Added some data types according to the GL-Syntax         (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.2   - Fixed some problems with getting the addresses of some&lt;br /&gt;
                Extensions (e.g. glTexImage3D) where the EXT/ARB did work&lt;br /&gt;
                but not the core-functions                               (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3   - A second call to ReadimplementationProperties won't&lt;br /&gt;
                revert to the default libs anymore                       (MW)&lt;br /&gt;
              - Libraries now will be released if necessary              (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3a  - Small fixes for glSlang-functions                        (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3b  - Fixed a small bug with GL_ARB_shader_objects, that lead&lt;br /&gt;
                lead to that extension not loaded correctly              (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3c  - More GL 1.5 compliance by FOG_COORD_xx and&lt;br /&gt;
                ARB-less VBO and occlusion query routines                (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3d  - Fixed linebreaks (should now be corrected under D5)      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4   - Changed header to correspond to the OpenGL-Shading&lt;br /&gt;
              - Language specification 1.10 :&lt;br /&gt;
                 - Added new GL_SAMPLER_*-Constants&lt;br /&gt;
                 - Added Constant GL_SHADING_LANGUAGE_VERSION_ARB&lt;br /&gt;
                 - Added Constant GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB&lt;br /&gt;
              - Added Constant GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB    (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4a  - Fixed a missing stdcall for glBindAttribLocationARB      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4b  - Fixed declaration for glUniform*(f/i)vARB (added count)  (MW)&lt;br /&gt;
              - glCompileShaderARB changed from function to procedure    (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.5   - Added support for FreePascal                             (BR)&lt;br /&gt;
              - Added type TGLVectorf3/TGLVector3f                       (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.6   - Added Extension GL_EXT_framebuffer_object                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.7   - Added Extension GL_ARB_fragment_program_shadow           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_color_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_pixel                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_float                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_depth_bounds_test                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_mirror_clamp              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_blend_equation_separate           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_dxt1          (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program_option            (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program2                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program2_option             (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program3                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.8   - Added explicit delegate type definitions                 (LM)&lt;br /&gt;
              - Added .Net 1.1 Support                                   (LM)&lt;br /&gt;
              - Added .Net overloaded functions                          (LM)&lt;br /&gt;
              - Added delayed extension loading and stubs                (LM)&lt;br /&gt;
              - Added automatic InitOpenGL call in CreateRenderingContext(LM)&lt;br /&gt;
              - Added extra Read_* function                              (LM)&lt;br /&gt;
&lt;br /&gt;
Version 2.0   - fixed some Problem with version string and damn drivers.&lt;br /&gt;
                String 1.15 identified as OpenGL 1.5 not as OpenGL 1.1   (SX)&lt;br /&gt;
              - Removed unexisting extension GL_ARB_texture_mirror_repeat(SX)&lt;br /&gt;
              - Added Extension WGL_ARB_pixel_format_float               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_stencil_clear_tag                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_edge_clamp                (SX)&lt;br /&gt;
              - Some 1.5 Core Consts added (now completed)               (SX)&lt;br /&gt;
              - gluProject need pointer for not .net                     (SX)&lt;br /&gt;
              - gluUnProject need pointer for not .net                   (SX)&lt;br /&gt;
              - wglUseFontOutlines* need pointer for not .net            (SX)&lt;br /&gt;
              - wglSwapMultipleBuffers need pointer for not .net         (SX)&lt;br /&gt;
              - Bug with wglGetExtensionsStringEXT removed&lt;br /&gt;
                different type for .net                                  (SX)&lt;br /&gt;
              - Added OpenGL 2.0 Core                                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.0.1 - fixed some problems with glGetActiveAttrib in 2.0 Core   (SX)&lt;br /&gt;
              - fixes some problems with gluProject                      (SX)&lt;br /&gt;
              - fixes some problems with gluUnProject                    (SX)&lt;br /&gt;
              - fixes some problems with gluTessVertex                   (SX)&lt;br /&gt;
              - fixes some problems with gluLoadSamplingMatrices         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.1   - Removed .NET Support                                     (SX)&lt;br /&gt;
              - Better support for Linux                                 (SX)&lt;br /&gt;
              - Better Codeformation                                     (SX)&lt;br /&gt;
              - Added some more Vector/Matrix types                      (SX)&lt;br /&gt;
              - Added OpenGL 2.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_depth_stencil              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_blit                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_multisample           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_program_parameters            (SX)&lt;br /&gt;
              - Added Extension GL_EXT_bindable_uniform                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_buffers2                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_shader4                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_float                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_array                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_latc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_integer                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_shared_exponent           (SX)&lt;br /&gt;
              - Added Extension GL_NV_depth_buffer_float                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_framebuffer_multisample_coverage   (SX)&lt;br /&gt;
              - Added Extension GL_NV_geometry_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program4                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object            (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program4                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0   - fixed some consts of GL_EXT_texture_shared_exponent       (SX)&lt;br /&gt;
              - possible better support for mac                          (SX)&lt;br /&gt;
              - Added OpenGL 3.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_object                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_vertex                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_range                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rg                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_object               (SX)&lt;br /&gt;
              - Added Extension GL_NV_conditional_render                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_present_video                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_transform_feedback                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_direct_state_access               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_NV_explicit_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback2                (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension WGL_NV_present_video                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_out                         (SX)&lt;br /&gt;
              - Added Extension WGL_NV_swap_group                        (SX)&lt;br /&gt;
              - Added define DGL_TINY_HEADER to suppress automatic&lt;br /&gt;
                function loading                                         (SX)&lt;br /&gt;
              - glProcedure renamed to dglGetProcAddress and now it's&lt;br /&gt;
                visible from outside the unit to custom load functions   (SX)&lt;br /&gt;
              - dglCheckExtension added to check if an extension exists  (SX)&lt;br /&gt;
              - Read_GL_ARB_buffer_object renamed to&lt;br /&gt;
                Read_GL_ARB_vertex_buffer_object                         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.1 - fixed a problem with fpc                                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.2 - fixed a problem with WGL_ARB_create_context             (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2   - Functions from GL_VERSION_3_0 where updated              (SX)&lt;br /&gt;
              - Functions from GL_ARB_map_buffer_range where updated     (SX)&lt;br /&gt;
              - Functions from GL_NV_present_video where added           (SX)&lt;br /&gt;
              - Added consts of GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Defines to identify Delphi was changed (prevent for          &lt;br /&gt;
                feature maintenance)                                     (SX)&lt;br /&gt;
              - Added Extension GL_ATI_meminfo                           (SX)&lt;br /&gt;
              - Added Extension GL_AMD_performance_monitor               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_texture_texture4                  (SX)&lt;br /&gt;
              - Added Extension GL_AMD_vertex_shader_tesselator          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension WGL_AMD_gpu_association                  (SX)&lt;br /&gt;
              - Added OpenGL 3.1 Core                                    (SX)&lt;br /&gt;
              - All deprecated stuff can be disabled if you undef the        &lt;br /&gt;
                define DGL_DEPRECATED                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_uniform_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_compatibility                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_copy_buffer                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_texture_lod                (SX)&lt;br /&gt;
              - Remove function from GL_NV_present_video                 (SX)&lt;br /&gt;
              - Added Extension WGL_3DL_stereo_control                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_snorm                     (SX)&lt;br /&gt;
              - Added Extension GL_AMD_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_texture_range                   (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_float_pixels                    (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_vertex_program_evaluators       (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_aux_depth_stencil               (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_object_purgeable                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_row_bytes                       (SX)&lt;br /&gt;
              - Added OpenGL 3.2 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_clamp                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_elements_base_vertex         (SX)&lt;br /&gt;
              - Added Extension GL_ARB_fragment_coord_conventions        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_seamless_cube_map                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sync                              (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sample_shading                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_cube_map_array            (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_gather                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_query_lod                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added GLX Core up to Version 1.4                         (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_multisample                      (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_fbconfig_float                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_get_proc_address                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_info                      (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_rating                    (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_import_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_fbconfig_packed_float            (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_texture_from_pixmap              (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.1 - Fixed some problems with Delphi &amp;lt; 6                      (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.2 - Added Extension GL_APPLE_rgb_422                         (SX)&lt;br /&gt;
              - Added Extension GL_EXT_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_NV_video_capture                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_copy_image                         (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object2           (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_load                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_buffer_unified_memory       (SX)&lt;br /&gt;
              - Added Extension GL_NV_texture_barrier                    (SX)&lt;br /&gt;
              - Variable GL_EXT_texture_snorm will be filled             (SX)&lt;br /&gt;
              - Variable GL_APPLE_row_bytes will be filled               (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_capture                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_copy_image                        (SX)&lt;br /&gt;
              - WGL_NV_video_out now named WGL_NV_video_output           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_swap_control                     (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.3 - Fixed a Problem with glGetAttribLocation                (SX)&lt;br /&gt;
              - Added const GL_UNIFORM_BUFFER_EXT                        (SX)&lt;br /&gt;
              - Functions of GL_NV_texture_barrier now will be loaded    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.0   - Changes on Extension GL_ARB_texture_gather               (SX)&lt;br /&gt;
              - Changes on Extension GL_NV_shader_buffer_load            (SX)&lt;br /&gt;
              - Added OpenGL 3.3 Core                                    (SX)&lt;br /&gt;
              - Added OpenGL 4.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_AMD_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_seamless_cubemap_per_texture      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shading_language_include          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_bptc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_blend_func_extended               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_explicit_attrib_location          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_occlusion_query2                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sampler_objects                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_bit_encoding               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rgb10_a2ui                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_type_2_10_10_10_rev        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_indirect                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader5                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader_fp64                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_subroutine                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_tessellation_shader               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object_rgb32       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback2               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback3               (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1   - Possible fix some strange linux behavior                 (SX)&lt;br /&gt;
              - All function uses GL instead of TGL types                (SX)&lt;br /&gt;
              - GL_AMD_vertex_shader_tesselator will be read now         (SX)&lt;br /&gt;
              - GL_AMD_draw_buffers_blend will be read now               (SX)&lt;br /&gt;
              - Changes on glStencilFuncSeparate (GL_2_0)                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_2                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_3                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_4_0                                (SX)&lt;br /&gt;
              - Changes on GL_ARB_sample_shading                         (SX)&lt;br /&gt;
              - Changes on GL_ARB_texture_cube_map_array                 (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader5                            (SX)&lt;br /&gt;
              - Changes on GL_ARB_transform_feedback3                    (SX)&lt;br /&gt;
              - Changes on GL_ARB_sampler_objects                        (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader_fp64                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_element_array                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_vertex_array_range                   (SX)&lt;br /&gt;
              - Changes on GL_NV_transform_feedback                      (SX)&lt;br /&gt;
              - Changes on GL_NV_vertex_buffer_unified_memory            (SX)&lt;br /&gt;
              - Changes on GL_EXT_multi_draw_arrays                      (SX)&lt;br /&gt;
              - Changes on GL_EXT_direct_state_access                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_performance_monitor                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_seamless_cubemap_per_texture           (SX)&lt;br /&gt;
              - Changes on GL_EXT_geometry_shader4                       (SX)&lt;br /&gt;
              - Added OpenGL 4.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_ES2_compatibility                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_get_program_binary                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_precision                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_viewport_array                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_cl_event                          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_robustness                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_conservative_depth                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_shader_image_load_store           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program5                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_shader5                        (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_store                (SX)&lt;br /&gt;
              - Added Extension GL_NV_tessellation_program5              (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_attrib_integer_64bit        (SX)&lt;br /&gt;
              - Added Extension GL_NV_multisample_coverage               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_name_gen_delete                   (SX)&lt;br /&gt;
              - Added Extension GL_AMD_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_vdpau_interop                      (SX)&lt;br /&gt;
              - Added Extension GL_AMD_transform_feedback3_lines_triangles (SX)&lt;br /&gt;
              - Added Extension GL_AMD_depth_clamp_separate              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB_decode               (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension WGL_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
              - Added Extension WGL_NV_multisample_coverage              (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_vertex_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1a  - Fix for dglGetProcAddress with FPC and linux (def param) (SW)&lt;br /&gt;
&lt;br /&gt;
Version 4.2   - Added OpenGL 4.2 Core                                    (SW) &lt;br /&gt;
              - Added Extension GL_ARB_base_instance                     (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_420pack          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback_instanced      (SW) &lt;br /&gt;
              - Added Extension GL_ARB_compressed_texture_pixel_storage  (SW) &lt;br /&gt;
              - Added Extension GL_ARB_conservative_depth                (SW) &lt;br /&gt;
              - Added Extension GL_ARB_internalformat_query              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_alignment              (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_atomic_counters            (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shader_image_load_store           (SW) &lt;br /&gt;
              - Added Extension GL_ARB_shading_language_packing          (SW) &lt;br /&gt;
              - Added Extension GL_ARB_texture_storage                   (SW) &lt;br /&gt;
              - Added Extension WGL_NV_DX_interop                        (SW) &lt;br /&gt;
              - Added Define for WGL_EXT_create_context_es2_profile      (SW) &lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=GLX&amp;diff=25330</id>
		<title>GLX</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=GLX&amp;diff=25330"/>
				<updated>2011-08-06T17:40:45Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Allgemein */ Hinweis auf fehlende GLX-Unterstützung im DGL-Header entfernt, GLX ist da schon lange drin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= GLX =&lt;br /&gt;
== Allgemein ==&lt;br /&gt;
Die OpenGL Erweiterung für das X Window System (GLX) bietet Funktionen zum Erstellen eines OpenGL Kontexts und zum Verbinden dieses Kontexts mit einem Fenster auf dem im X Window System gezeichnet werden kann. GLX-Funktionen führen ähnlich wie [[WGL]]-Funktionen ein Prefix. In diesem Fall &amp;quot;glX&amp;quot;.&lt;br /&gt;
Unter Unix-Systemen (z.B. GNU/Linux, FreeBSD etc.) greift die Software nicht direkt auf Grafikkarte zu. Stattdessen gibt es eine Zwischenschicht, die meist umgangssprachlich als &amp;quot;X-Server&amp;quot; bezeichnet wird. Nahezu alle Anwendungen und grafischen Windowsmanager (z.B. [http://www.kde.org K Desktop Environment]) nutzen diese Schnittstelle zum zeichnen. GLX stellt die Erweiterung dar auf dem X-Server OpenGL-Funktionen auszuführen.&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
In der Praxis wird sich der Einsatz von GLX vermutlich eher nicht als lohnenend erweisen, da diese Erweiterung nur für das X Windows System zur Verfügung steht und somit nur auf den Unix-Systemen zur Verfügung steht. Das verwenden von GLX ist unter Windows nicht möglich. Gerade deshalb bietet es sich an statt GLX einzusetzen, auf [[SDL]] zurück zugreifen. Es stehen im Prinzip die gleichen Möglichkeiten wie mit GLX zur Verfügung, der Code wird allerdings auch anderen Betriebssystem (u.a. Windows) laufen. Es herrscht der Irrglaube, dass man GLX verwenden ''müßte'' um unter Linux OpenGL zu nutzen. Dem ist somit nicht so. Es sollte also in jedem Fall geprüft werden, ob sich der direkte Einsatz wirklich lohnt.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[WGL]], das Gegenstück für Windows&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Links ==&lt;br /&gt;
[http://utah-glx.sourceforge.net/ GLX-Projektseite]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25077</id>
		<title>Vorlage:dglOpenGL History</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Vorlage:dglOpenGL_History&amp;diff=25077"/>
				<updated>2011-03-14T16:40:59Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pascal&amp;gt;Version 1.0   - Initial Release&lt;br /&gt;
&lt;br /&gt;
Version 1.1   - Added PPointer in Tpyessection for compatiblity with Delphi&lt;br /&gt;
                versions lower than 7                                    (SW)&lt;br /&gt;
              - Added a function named RaiseLastOSError including a comment&lt;br /&gt;
                on how to make it run under Delphi versions lower than 7 (SW)&lt;br /&gt;
              - Added some data types according to the GL-Syntax         (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.2   - Fixed some problems with getting the addresses of some&lt;br /&gt;
                Extensions (e.g. glTexImage3D) where the EXT/ARB did work&lt;br /&gt;
                but not the core-functions                               (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3   - A second call to ReadimplementationProperties won't&lt;br /&gt;
                revert to the default libs anymore                       (MW)&lt;br /&gt;
              - Libraries now will be released if necessary              (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3a  - Small fixes for glSlang-functions                        (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3b  - Fixed a small bug with GL_ARB_shader_objects, that lead&lt;br /&gt;
                lead to that extension not loaded correctly              (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3c  - More GL 1.5 compliance by FOG_COORD_xx and&lt;br /&gt;
                ARB-less VBO and occlusion query routines                (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.3d  - Fixed linebreaks (should now be corrected under D5)      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4   - Changed header to correspond to the OpenGL-Shading&lt;br /&gt;
              - Language specification 1.10 :&lt;br /&gt;
                 - Added new GL_SAMPLER_*-Constants&lt;br /&gt;
                 - Added Constant GL_SHADING_LANGUAGE_VERSION_ARB&lt;br /&gt;
                 - Added Constant GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB&lt;br /&gt;
              - Added Constant GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB    (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4a  - Fixed a missing stdcall for glBindAttribLocationARB      (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.4b  - Fixed declaration for glUniform*(f/i)vARB (added count)  (MW)&lt;br /&gt;
              - glCompileShaderARB changed from function to procedure    (MW)&lt;br /&gt;
&lt;br /&gt;
Version 1.5   - Added support for FreePascal                             (BR)&lt;br /&gt;
              - Added type TGLVectorf3/TGLVector3f                       (SW)&lt;br /&gt;
&lt;br /&gt;
Version 1.6   - Added Extension GL_EXT_framebuffer_object                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.7   - Added Extension GL_ARB_fragment_program_shadow           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_color_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_pixel                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_float                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_depth_bounds_test                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_mirror_clamp              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_blend_equation_separate           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_pixel_buffer_object               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_dxt1          (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program_option            (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program2                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program2_option             (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program3                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 1.8   - Added explicit delegate type definitions                 (LM)&lt;br /&gt;
              - Added .Net 1.1 Support                                   (LM)&lt;br /&gt;
              - Added .Net overloaded functions                          (LM)&lt;br /&gt;
              - Added delayed extension loading and stubs                (LM)&lt;br /&gt;
              - Added automatic InitOpenGL call in CreateRenderingContext(LM)&lt;br /&gt;
              - Added extra Read_* function                              (LM)&lt;br /&gt;
&lt;br /&gt;
Version 2.0   - fixed some Problem with version string and damn drivers.&lt;br /&gt;
                String 1.15 identified as OpenGL 1.5 not as OpenGL 1.1   (SX)&lt;br /&gt;
              - Removed unexisting extension GL_ARB_texture_mirror_repeat(SX)&lt;br /&gt;
              - Added Extension WGL_ARB_pixel_format_float               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_stencil_clear_tag                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_rectangle                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_edge_clamp                (SX)&lt;br /&gt;
              - Some 1.5 Core Consts added (now completed)               (SX)&lt;br /&gt;
              - gluProject need pointer for not .net                     (SX)&lt;br /&gt;
              - gluUnProject need pointer for not .net                   (SX)&lt;br /&gt;
              - wglUseFontOutlines* need pointer for not .net            (SX)&lt;br /&gt;
              - wglSwapMultipleBuffers need pointer for not .net         (SX)&lt;br /&gt;
              - Bug with wglGetExtensionsStringEXT removed&lt;br /&gt;
                different type for .net                                  (SX)&lt;br /&gt;
              - Added OpenGL 2.0 Core                                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.0.1 - fixed some problems with glGetActiveAttrib in 2.0 Core   (SX)&lt;br /&gt;
              - fixes some problems with gluProject                      (SX)&lt;br /&gt;
              - fixes some problems with gluUnProject                    (SX)&lt;br /&gt;
              - fixes some problems with gluTessVertex                   (SX)&lt;br /&gt;
              - fixes some problems with gluLoadSamplingMatrices         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 2.1   - Removed .NET Support                                     (SX)&lt;br /&gt;
              - Better support for Linux                                 (SX)&lt;br /&gt;
              - Better Codeformation                                     (SX)&lt;br /&gt;
              - Added some more Vector/Matrix types                      (SX)&lt;br /&gt;
              - Added OpenGL 2.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_depth_stencil              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_blit                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_multisample           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_program_parameters            (SX)&lt;br /&gt;
              - Added Extension GL_EXT_bindable_uniform                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_buffers2                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_EXT_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_EXT_gpu_shader4                       (SX)&lt;br /&gt;
              - Added Extension GL_EXT_packed_float                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_array                     (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_latc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_integer                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_shared_exponent           (SX)&lt;br /&gt;
              - Added Extension GL_NV_depth_buffer_float                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_fragment_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_framebuffer_multisample_coverage   (SX)&lt;br /&gt;
              - Added Extension GL_NV_geometry_program4                  (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program4                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object            (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_program4                    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0   - fixed some const of GL_EXT_texture_shared_exponent       (SX)&lt;br /&gt;
              - possible better support for mac                          (SX)&lt;br /&gt;
              - Added OpenGL 3.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_buffer_float                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_instanced                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_object                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_framebuffer_sRGB                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_geometry_shader4                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_half_float_vertex                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_map_buffer_range                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_rgtc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rg                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_object               (SX)&lt;br /&gt;
              - Added Extension GL_NV_conditional_render                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_present_video                      (SX)&lt;br /&gt;
              - Added Extension GL_EXT_transform_feedback                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_direct_state_access               (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_NV_explicit_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_NV_transform_feedback2                (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension WGL_NV_present_video                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_out                         (SX)&lt;br /&gt;
              - Added Extension WGL_NV_swap_group                        (SX)&lt;br /&gt;
              - Added define DGL_TINY_HEADER to suppress automatic&lt;br /&gt;
                function loading                                         (SX)&lt;br /&gt;
              - glProcedure renamed to dglGetProcAddress and now it's&lt;br /&gt;
                visible from outside the unit to custom load functions   (SX)&lt;br /&gt;
              - dglCheckExtension added to check if an extension exists  (SX)&lt;br /&gt;
              - Read_GL_ARB_buffer_object renamed to&lt;br /&gt;
                Read_GL_ARB_vertex_buffer_object                         (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.1 - fixed an problem with fpc                                (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.0.2 - fixed an problem with WGL_ARB_create_context             (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2   - Functions from GL_VERSION_3_0 where updated              (SX)&lt;br /&gt;
              - Functions from GL_ARB_map_buffer_range where updated     (SX)&lt;br /&gt;
              - Functions from GL_NV_present_video where added           (SX)&lt;br /&gt;
              - Added consts of GL_ARB_instanced_arrays                  (SX)&lt;br /&gt;
              - Defines to identify Delphi was changed (prevent for          &lt;br /&gt;
                feature maintenance)                                     (SX)&lt;br /&gt;
              - Added Extension GL_ATI_meminfo                           (SX)&lt;br /&gt;
              - Added Extension GL_AMD_performance_monitor               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_texture_texture4                  (SX)&lt;br /&gt;
              - Added Extension GL_AMD_vertex_shader_tesselator          (SX)&lt;br /&gt;
              - Added Extension GL_EXT_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension WGL_AMD_gpu_association                  (SX)&lt;br /&gt;
              - Added OpenGL 3.1 Core                                    (SX)&lt;br /&gt;
              - All deprecated stuff can be disabled if you undef the        &lt;br /&gt;
                define DGL_DEPRECATED                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_uniform_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GL_ARB_compatibility                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_copy_buffer                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_texture_lod                (SX)&lt;br /&gt;
              - Remove function from GL_NV_present_video                 (SX)&lt;br /&gt;
              - Added Extension WGL_3DL_stereo_control                   (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_snorm                     (SX)&lt;br /&gt;
              - Added Extension GL_AMD_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_texture_range                   (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_float_pixels                    (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_vertex_program_evaluators       (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_aux_depth_stencil               (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_object_purgeable                (SX)&lt;br /&gt;
              - Added Extension GL_APPLE_row_bytes                       (SX)&lt;br /&gt;
              - Added OpenGL 3.2 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_depth_clamp                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_elements_base_vertex         (SX)&lt;br /&gt;
              - Added Extension GL_ARB_fragment_coord_conventions        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_provoking_vertex                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_seamless_cube_map                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sync                              (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_multisample               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_array_bgra                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_buffers_blend                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sample_shading                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_cube_map_array            (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_gather                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_query_lod                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added GLX Core up to Version 1.4                         (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_multisample                      (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_fbconfig_float                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_get_proc_address                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_profile           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_info                      (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_visual_rating                    (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_import_context                   (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_fbconfig_packed_float            (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_texture_from_pixmap              (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.1 - Fixed some problems with Delphi &amp;lt; 6                      (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.2 - Added Extension GL_APPLE_rgb_422                         (SX)&lt;br /&gt;
              - Added Extension GL_EXT_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_NV_video_capture                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_copy_image                         (SX)&lt;br /&gt;
              - Added Extension GL_NV_parameter_buffer_object2           (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_load                 (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_buffer_unified_memory       (SX)&lt;br /&gt;
              - Added Extension GL_NV_texture_barrier                    (SX)&lt;br /&gt;
              - Variable GL_EXT_texture_snorm will be filled             (SX)&lt;br /&gt;
              - Variable GL_APPLE_row_bytes will be filled               (SX)&lt;br /&gt;
              - Added Extension WGL_NV_video_capture                     (SX)&lt;br /&gt;
              - Added Extension WGL_NV_copy_image                        (SX)&lt;br /&gt;
              - WGL_NV_video_out now named WGL_NV_video_output           (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_swap_control                     (SX)&lt;br /&gt;
&lt;br /&gt;
Version 3.2.3 - Fixed an Problem with glGetAttribLocation                (SX)&lt;br /&gt;
              - Added const GL_UNIFORM_BUFFER_EXT                        (SX)&lt;br /&gt;
              - Functions of GL_NV_texture_barrier now will be loaded    (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.0   - Changes on Extension GL_ARB_texture_gather               (SX)&lt;br /&gt;
              - Changes on Extension GL_NV_shader_buffer_load            (SX)&lt;br /&gt;
              - Added OpenGL 3.3 Core                                    (SX)&lt;br /&gt;
              - Added OpenGL 4.0 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_AMD_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_seamless_cubemap_per_texture      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shading_language_include          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_compression_bptc          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_blend_func_extended               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_explicit_attrib_location          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_occlusion_query2                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_sampler_objects                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_bit_encoding               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_rgb10_a2ui                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_swizzle                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_timer_query                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_type_2_10_10_10_rev        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_draw_indirect                     (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader5                       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_gpu_shader_fp64                   (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_subroutine                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_tessellation_shader               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_texture_buffer_object_rgb32       (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback2               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_transform_feedback3               (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1   - Possible fix some strange linux behavior                 (SX)&lt;br /&gt;
              - All function uses GL instead of TGL types                (SX)&lt;br /&gt;
              - GL_AMD_vertex_shader_tesselator will be read now         (SX)&lt;br /&gt;
              - GL_AMD_draw_buffers_blend will be read now               (SX)&lt;br /&gt;
              - Changes on glStencilFuncSeparate (GL_2_0)                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_2                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_3_3                                (SX)&lt;br /&gt;
              - Changes on GL_VERSION_4_0                                (SX)&lt;br /&gt;
              - Changes on GL_ARB_sample_shading                         (SX)&lt;br /&gt;
              - Changes on GL_ARB_texture_cube_map_array                 (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader5                            (SX)&lt;br /&gt;
              - Changes on GL_ARB_transform_feedback3                    (SX)&lt;br /&gt;
              - Changes on GL_ARB_sampler_objects                        (SX)&lt;br /&gt;
              - Changes on GL_ARB_gpu_shader_fp64                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_element_array                        (SX)&lt;br /&gt;
              - Changes on GL_APPLE_vertex_array_range                   (SX)&lt;br /&gt;
              - Changes on GL_NV_transform_feedback                      (SX)&lt;br /&gt;
              - Changes on GL_NV_vertex_buffer_unified_memory            (SX)&lt;br /&gt;
              - Changes on GL_EXT_multi_draw_arrays                      (SX)&lt;br /&gt;
              - Changes on GL_EXT_direct_state_access                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_performance_monitor                    (SX)&lt;br /&gt;
              - Changes on GL_AMD_seamless_cubemap_per_texture           (SX)&lt;br /&gt;
              - Changes on GL_EXT_geometry_shader4                       (SX)&lt;br /&gt;
              - Added OpenGL 4.1 Core                                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_ES2_compatibility                 (SX)&lt;br /&gt;
              - Added Extension GL_ARB_get_program_binary                (SX)&lt;br /&gt;
              - Added Extension GL_ARB_separate_shader_objects           (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_precision                  (SX)&lt;br /&gt;
              - Added Extension GL_ARB_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_ARB_viewport_array                    (SX)&lt;br /&gt;
              - Added Extension GL_ARB_cl_event                          (SX)&lt;br /&gt;
              - Added Extension GL_ARB_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_ARB_robustness                        (SX)&lt;br /&gt;
              - Added Extension GL_ARB_shader_stencil_export             (SX)&lt;br /&gt;
              - Added Extension GL_AMD_conservative_depth                (SX)&lt;br /&gt;
              - Added Extension GL_EXT_shader_image_load_store           (SX)&lt;br /&gt;
              - Added Extension GL_EXT_vertex_attrib_64bit               (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_program5                       (SX)&lt;br /&gt;
              - Added Extension GL_NV_gpu_shader5                        (SX)&lt;br /&gt;
              - Added Extension GL_NV_shader_buffer_store                (SX)&lt;br /&gt;
              - Added Extension GL_NV_tessellation_program5              (SX)&lt;br /&gt;
              - Added Extension GL_NV_vertex_attrib_integer_64bit        (SX)&lt;br /&gt;
              - Added Extension GL_NV_multisample_coverage               (SX)&lt;br /&gt;
              - Added Extension GL_AMD_name_gen_delete                   (SX)&lt;br /&gt;
              - Added Extension GL_AMD_debug_output                      (SX)&lt;br /&gt;
              - Added Extension GL_NV_vdpau_interop                      (SX)&lt;br /&gt;
              - Added Extension GL_AMD_transform_feedback3_lines_triangles (SX)&lt;br /&gt;
              - Added Extension GL_AMD_depth_clamp_separate              (SX)&lt;br /&gt;
              - Added Extension GL_EXT_texture_sRGB_decode               (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension WGL_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension WGL_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
              - Added Extension WGL_NV_multisample_coverage              (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_vertex_buffer_object             (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_framebuffer_sRGB                 (SX)&lt;br /&gt;
              - Added Extension GLX_ARB_create_context_robustness        (SX)&lt;br /&gt;
              - Added Extension GLX_EXT_create_context_es2_profile       (SX)&lt;br /&gt;
&lt;br /&gt;
Version 4.1a  - Fix for dglGetProcAddress with FPC and linux (def param) (SW)&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25069</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=25069"/>
				<updated>2011-03-07T14:55:28Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Versionsnummer aktualisiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
So to compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easily (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 4.1) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extensions that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check wether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}}'''&lt;br /&gt;
&lt;br /&gt;
(Supports ''OpenGL 4.1'', works with Delphi 4 and up and Freepascal))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')''&lt;br /&gt;
&lt;br /&gt;
''(Note : This header is'nt developed any further)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Link&amp;diff=25002</id>
		<title>Link</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Link&amp;diff=25002"/>
				<updated>2011-01-10T12:36:13Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Beispiele/Demos mit Quelltext */  Link zur Seite von Humus geändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
!!!!!!!! NUTZT DIESE TABELLE ALS VORLAGE FÜR WEITERE LINKTABELLEN !!!!!!!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[Link]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[Link]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Links die mit Grafik/OpenGL zu tun haben =&lt;br /&gt;
Hier finden Sie eine Übersicht von Links. &lt;br /&gt;
&lt;br /&gt;
*Weitere Navigations Links findet Sie unter [[DGL Wiki:Portal]]&lt;br /&gt;
*Links zu Tools oder Programmen finden Sie unter [[Tool]]s&lt;br /&gt;
&lt;br /&gt;
== Hardwareinfos ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://delphi3d.net/hardware/listreports.php OpenGL Hardware Registry - Hardwareübersicht]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Datenbank aller Grafikkarten die in der Harware Registry vorhanden sind. Die einzelnen Artikel enthalten Infos darüber, welche Extensions von der Grafikkarte unterstützt werden.&lt;br /&gt;
|-&lt;br /&gt;
|[http://delphi3d.net/hardware/allexts.php OpenGL Hardware Registry - Extensionübersicht]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Datenbank aller Extensions die in der Harware Registry vorhanden sind. Die einzelnen Artikel enthalten Infos darüber, welche Grafikkarten die entsprechende Extension unterstützen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
||[[Tutorial|DGL Wiki - Tutorial]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|DelphiGL.com ist Betreiber dieses Wikis und stellt eine Vielzahl Tutorials mit Schwehrpunkt OpenGL zur Verfügung. &lt;br /&gt;
Neben Tutorials für Einsteiger und OpenGL Anfänger gibt es auch fortgeschrittene Themen wie Shader oder Partikelsysteme.Sprache der Wahl ist hier Delphi.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.joachimrohde.com/cms/xoops/modules/articles/index.php?cat_id=1 joachimrohde.com]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet ihr deutsche Übersetzungen der bekannten NeHe Tutorials. Sprache der Wahl ist hier C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.cg.tuwien.ac.at/studentwork/VRSem96/OpenGL/ Technische Universität Wien]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://nehe.gamedev.net/ Nehe] &lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die berühmt berüchtigten NeHe Tutorials sind eine umfangreiche Sammlung an Tutorials zum Thema OpenGL. Von Anfängertutorials bis hin zu komplexen Effekten wird alles behandelt. Sprache der Wahl ist hier C++. (Eine Übersetzung der NeHe Tutorials findet ihr bei Joachim Rhode (siehe oben). )&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.sulaco.co.za/tut.htm sulaco.co.za] &lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| OpenGL Beispiele in Delphi&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textur Erstellung ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://3d.diehlsworld.de/textures/index.htm 3d.diehlsworld.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet ihr kurze aber inhaltlich reiche Tutorials zu der Frage &amp;quot;Wie erstelle ich XXXXX-Texturen&amp;quot;. Dabei reicht die Palette von Untergrundtexturen wie Gras, Sand , Fels und Wasser (und Kombinationen dieser) bis hin zu Blitzen und Partikeln. Als Programm wird hier Photoshop verwendet.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gimps.de/gimp/textur-muster/ gimps.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Schritt für Schritt Anleitungen wie man mit Gimp verschiedene Texturen erstellt.&lt;br /&gt;
|-&lt;br /&gt;
|[http://cbt.k090999.de/gimp.php#texturen k090999.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Gimptutorials zum Erstellen verschiedene Texturen.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Blender ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://blendpolis.de/f/viewtopic.php?t=5786 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Ein Thread im Forum von [http://blendpolis.de Blendpolis] in dem '''sehr''' viele Tutorials aufgelistet sind&lt;br /&gt;
|-&lt;br /&gt;
|[http://blendpolis.de/f/article_cat.php?fldAuto=7 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Eigentliche Tutorial Seite von [http://blendpolis.de Blendpolis] die Auswahl ist hier aber nicht so groß&lt;br /&gt;
|-&lt;br /&gt;
|[http://wikivid.com/index.php/Blender Blender at wikivid.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Linksammlung von Blender Video Tutorials&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.blender.org/education-help/tutorials/getting-started/ blender3d.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Auch die Heimatseite von Blender bietet viele Tutorials unter anderm auch Video Tuorials&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.Blenderunderground.com Blenderunderground]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| '''sehr gute''' Video-Tutorials&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenGL Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== GL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GL|DGL Wiki - Kategorie GL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten OpenGL Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL.tar.gz OpenGL.org - Orginal Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die Orginalspezifikationen der OpenGL 1.0 und OpenGL 1.1 Befehle. (Diese HTML-Dokumente sind nicht Copy&amp;amp;Paste freundlich, da sie vermutlich automatisch aus vorhandenen Dateien (Postscript) erzeugt wurden.)&lt;br /&gt;
|-&lt;br /&gt;
|[http://developer.3dlabs.com/documents/glmanpage_index.htm 3dLabs]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die Orginalspezifikationen der OpenGL 1.0 und OpenGL 1.1 Befehle.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von Englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc01_4f03.asp MSDN von Microsoft]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|OpenGL Dokumentation in der MSDN. Die Erklärung der MSDN sind meist keine reinen Kopien der Orginalspezifikationen, sondern enthalten hin und wieder auch zusätzliche Informationen, oder formulieren Texte auf verständlichere Art und Weise.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLU ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GLU|DGL Wiki - Kategorie GLU]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten GLU Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/ OpenGL.org - Orginal Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Orginalspezifikationen für die GLU Befehle. (Diese HTML-Dokumente sind nicht Copy&amp;amp;Paste freundlich, da sie vermutlich automatisch aus vorhandenen Dateien (Postscript) erzeugt wurden.)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glufnc01_0e43.asp MSDN von Microsoft]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|GLU Dokumentation in der MSDN. Die Erklärung der MSDN sind meist keine reinen Kopien der Orginalspezifikationen, sondern enthalten hin und wieder auch zusätzliche Informationen, oder formulieren Texte auf verständlichere Art und Weise.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLX ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GLX|DGL Wiki - Kategorie GLX]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten GLX Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glx/ OpenGL.org - Orginal  Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Orgninalspezifikationen der GLX Befehle bei OpenGL.org.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von Englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== WGL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:WGL|DGL Wiki - Kategorie WGL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Wiki-Kategorie die alle übersetzten WGL Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://developer.3dlabs.com/documents/wglmanpage_index.htm 3dLabs]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung einiger WGL Befehlsspezifikationen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLUT ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://freeglut.sourceforge.net/docs/api.php The freeglut Projekt]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Englischsprachige Dokumentation zum OpenGL Utility Toolkit kurz GLUT.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SDL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:SDL|DGL Wiki - Kategorie SDL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Übersicht aller auf die SDL bezogenen Artikel hier im Wiki. Darunter befinden sich eine Vielzahl von Übersetzungen der SDL Befehlspezifikationen. Diese können auch in der [[SDL-Funktionsübersicht]] gefunden werden.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.libsdl.org/cgi/docwiki.cgi/SDL_20API libsdl.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Das Dokumentationswiki von libSDL.org enthält die komplette Dokumenation zur SDL in englischer Sprache.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.fp.sdl.de.vu/ fp.sdl.de.vu]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Eine Webseite die speziell Informationen über die Programmierung von SDL unter Freepascal zur Verfügung stellt.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[FAQ| DGL Wiki - FAQ]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Ein FAQ (Frequently Asked Questions = Häufig gestellte Fragen) zu DelphiGL.com und dem DGL Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dsource.de/faq/index.htm 3dsource.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Ein FAQ zu Fragen rund um OpenGL.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Effekte und Techniken mit OpenGL ==&lt;br /&gt;
&lt;br /&gt;
===Glow===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamasutra.com/view/feature/2107/realtime_glow.php Gamasutra]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt, wie man mit Hilfe von Shader(hier DirectX Shader) den Gloweffekt in Realtime umsetzt. Dabei wird erst die Technik dahinter erklährt, und dann wie man sie Schritt für Schritt umsetzt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://collective.valve-erc.com/index.php?go=tron1 valve-erc.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Schritt für Schritt Anleitung, wie man mit Hilfe von Cg in OpenGL den Glow Effekt realisieren kann &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===HDR===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/columns/hardcore/hdrrendering/ gamedev.net]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Hier wird sehr kurz eingeleitet, was HDR Rendering überhaupt ist, dann wird der Aufbau des *.hdr Formats erläutert, und dann geht es schon von 0 auf 100 zum Programmieren. Erklährungen gibt es kaum, dafür werden fertige Shader(für DirectX) geboten. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/reference/articles/article2208.asp gamedev.net]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt auch nur etwas kurz das HDR Verfahren, jedoch mit mehr mathematischen Hintergrund in Sachen Tonemapping. Beispielcode für Tonemapping in C++ liegt bei. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===BSP Bäume===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dtechdev.com/tutorials/leafbsp/3dbsptrees.html 3dtechdev.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Das beste Dokument überhaupt, für allem die selber BSP Bäume compilieren möchte. Ist belegt mit sehr viel Grafik. Erst beginnt er das Prinzip allgemein zum umschreiben, dann wird alles genau erläutert, und mit verständlichen Pseudocode untermalt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dtechdev.com/tutorials/illegalgeometry/illegalgeometrytut.html 3dtechdev.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Nicht ganz so gut geworden, wie sein erstes Tutorial, aber erklährt auch sehr gut, wie man illegale Geometrie aufspürt und beseitigt. Wieder mit Grafiken und Pseudocodes verständlich belegt. Hiermit kann man seinem Map-Compiler den letzten Schliff verleien. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/reference/articles/article981.asp Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Von Michael Abrash, dürfte der ''Erfinder'' von Quake sein. Naja, meine Englischkenntnisse reichen hier nicht ganz aus, um den Text zu verstehen. Ist etwas umständlich geschrieben. Dafür mit Grafiken unterlegt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.zfx-online.de/Tutorials.php?ID=11 Part 1 - Allgemein]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Einzigste deutsche Referenz zu BSP Bäumen, dafür Daumen hoch. Ist aber nicht das Wahre: schlechter C Code, und ich hatte auch nicht den Einduck, das er die Theorie zu diesem Thema bis in die Tiefe verstanden hat(oder er wollte es nicht zu akademisch Erklähren oO). Aber ein guter Einstieg in dieses Thema. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.zfx-online.de/Tutorials.php?ID=13 Part 2 - Kollision und PVS]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.cs.uwec.edu/~stevende/cs455/programs/GameTutorials%20-%20Quake%203%20BSP%20Format.htm Quake3 *.bsp Format]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die beste Dokumentation für das BSP Format, die ich gefunden habe, besser als den Quake3 Sourcecode zu durchforsten. Leider etwas magere Eklährung zu wichtigen Themen wie Patches(Curved Surfaces). Ich pers. hatte jetzt 1 1/2 Wochen gebraucht, um das *.bsp Format vollständig zu verstehen. Ist aber anscheinend die beste Format Dokumentation im Netz. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_q2bsp.shtml Quake2 *.bsp Format]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Kann auch nur soviel sagen, wie beim Link zuvor. Es fehlen hier auch zum Teil Informationen. Man muss halt viel ausprobieren, und sich den Quake 2 Source zu Herzen nehmen, damit man es versteht. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Himmel &amp;amp; Wolken===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/community/forums/topic.asp?topic_id=86024 Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Guter Thread mit vielen Anregungen und Links. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/community/forums/topic.asp?topic_id=135654 Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Hier wird die Diskussion zum obigen Link weitergeführt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://freespace.virgin.net/hugo.elias/models/m_clouds.htm Plasma]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine nette Idee um Plasma in Echtzeit zu generieren, und zu verändern. Leider nichts zum Shading. &lt;br /&gt;
|-&lt;br /&gt;
|[http://nis-lab.is.s.u-tokyo.ac.jp/~nis/cdrom/sig00_cloud.pdf 3D Wolken]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Paper über generieren und rendern von 3 dimensionalen Wolken inklusive Schatten und Lichtstrahlen. Ich hab nur den Lichtstahlen-Algorithmus ausprobiert. Saulangsam aber sehr einfach zu implementieren. Einen Blick ist es auf jeden Fall wert. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.geocities.com/ngdash/whitepapers/skydomecolor.html Skydome]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Wenn man mal schnell gute Farben für seinen Skydome braucht... &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Terrain===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_geomipmaps.shtml FlipCode]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Artikel zu Geomipmaping. Zummindest hab ich es hier zum ersten mal gesehen. Und es funzt ganz gut. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.vterrain.org Virtual Terrain Project]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Seite mit Links und Artikeln zu allem, was etwas mit Terrainrendering zu tun hat.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sonstiges===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[Materialsammlung]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Sammlung von gängigen Parametern für [[glMaterial]] hier im Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|[http://freespace.virgin.net/hugo.elias/radiosity/radiosity.htm Radiosity]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Erklährt sehr schön die Funktionsweise von Radiosity, liefert Beispielcodes und ist recht gut illustriert.&lt;br /&gt;
|-&lt;br /&gt;
|[http://legion.gibbering.net/projectx/paper/shadow%20mapping/ Shadowmapping]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt das Trapezoidal Shadow Mapping - Verfahren für gerichte Lichter.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_generatingnames.shtml Namensgenerator]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Per Zufallsgenrator Namen erzeugen, und nie wieder kreativ werden müssen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.paulsprojects.net/tutorials/simplebump/simplebump.html Bumpmapping]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Bumpmapping auf Lowend-Grakas. Damals war Bumpmapping noch was ganz tolles... &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.paulsprojects.net/opengl/dpreflect/dpreflect.html Dot Product Reflect]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|zwar nur ne Demo, aber wenn man schon immer mal mit EMBM das Wasser aus Morrowind nachproggen wollte... &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beispiele/Demos mit Quelltext ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.delphigl.de DelphiGL.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier finden sich besonders eindrucksvolle Newton Physik Demos. Meißtens sogar mit Quelltext.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.shadow3d.de.vu/ Shadow 3D]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier finden sich zwei Demos wie man Quake 3 Modelle lädt und eine glSlang Demo&lt;br /&gt;
|-&lt;br /&gt;
|[[Shadersammlung]] im DGL Wiki&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier findet man freie Shadersourcen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.humus.name Humus]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Diverse eindrucksvolle Demos zu verschiedenen Techniken, häufig mit Quelltext in C (teilweise OpenGL / DirectX)&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== weitere Links ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www-user.tu-chemnitz.de/~pester/Lehre/CompGeo.pdf CompGeo.pdf]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Script &amp;quot;Einführung in die Computergeometrie&amp;quot; von Dr. Pester (TU-Chemnitz). Ideales Nachschlagewerk für die Mathematik die einem bei der Grafikprogrammierung so begegnet.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.robsite.de/ robsite.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Auf dieser riesigen Seite finden sich auch viele weitere Links über verschiedene Themen der 3D Programmierung.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dlinks.com/links.cfm?categoryid=3&amp;amp;subcategoryid=21 3dlinks.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Diese Seite hat es sich zur Hauptaufgabe gemacht Links auf Seiten mit dem Thema 3D zu sammeln.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.two-kings.de/links.html two-kings.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Sammlung diverser interessanter Links, vorallem auf Themen im gamedev-Forum verweisend.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.delgine.com Delgine.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Heimat des freien 3D Modellers &amp;quot;DeleD&amp;quot;, welcher in Delphi programmiert ist. Ihr findet dort auch Modellpackete, Texturpackete, Plugins und Hilfe bei der Programmierung von Delphi und OpenGL.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Links zum Thema Spieleprogrammierung=&lt;br /&gt;
&lt;br /&gt;
==Allgemein==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.spieleprogrammierung.net/ Spieleprogrammierung - OpenGL - GLSL - OpenAL - KI - Animation - Spielephysik]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet Ihr Artikel, Tutorials und Programmbeispiele rund um das Thema Spieleprogrammierung. Programmiersprache ist hier C/C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://audio-framework.spieleprogrammierung.net/ OpenAL Audio Framework]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet Ihr ein frei verfügbares OpenAL Audio Framework (LGPL-Lizenz) samt zugehöriger Probammbeispiele. Unterstützt werden 3D Sounds, EFX (EAX Alternative) Reverb Effekte sowie Audio Streaming (Music and Voices). Programmiersprache ist hier C/C++.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Kopierschutz==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://inner-smile.com/nocrack.phtml Inner-Smile.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Seite mit Gedanken zum Thema &amp;quot;Wie schütze ich meine Programme vor Crackern&amp;quot;. Falls die Seite nicht erreichbar ist hat Google noch ne [http://www.google.com/search?q=cache:hpqPT5G4WB0J:www.inner-smile.com/nocrack.phtml+http://inner-smile.com/nocrack.phtml&amp;amp;hl=de&amp;amp;gl=de&amp;amp;ct=clnk&amp;amp;cd=1 Version im Archiv].&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==KI==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.kbs.uni-hannover.de/Lehre/KI2/Presentationen/presentation9798/esprit/spieltheorie/spieltheorie.html Uni-Hannover - Spieltheorie]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Artikel über die Grundlagen von KI in Spielen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.robsite.de/tutorials.php?tut=ki Robsite KI-Tutorials]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Sammlung von Texten zum Thema KI in Spielen. Beispiele sind meist in C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://ai-depot.com/ AI-Depot.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Seite die sich ausschließlich mit KI in Spielen beschäftigt.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.ai-junkie.com/links.html AI-Junkie.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Linkseite mit vielen KI relevanten Links. Die Seite AI-Junie selbst behandelt auch viele Themen rund um KI.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.aiwisdom.com/ AIWisdom.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Seite die sich mit KIs in Spielen beschäftigt und sich zum Ziel gesetzt hat, alle Artikel zum Thema zu finden und zu Katalogisieren. Es gibt hier auch Artikel über die KIs bestehender Spiele.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.aiguru.com/ AIGuru.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Newsseite zum Thema KI, Künstliches Leben, Hiernforschung, Robotik, Nanotechnologie - Halt alles was Spass macht.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.generation5.org/ Generation5.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Seite über KI, Robotik, etc. . Leider scheint die Seite Probleme zu haben regelmäßig aktualisiert zu werden. Aber zumindest sollte man einige Artikel finden. Die werden ja nicht schlecht.&lt;br /&gt;
|-&lt;br /&gt;
|www.gameai.com&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|''Wurde Januar 2010 als down gemeldet. Weiss irgendwer etwas genaueres?'' Seite zum Thema KI in Spielen. Soll wohl einen gewissen Stellenwert in der AI-Szene haben.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www-i1.informatik.rwth-aachen.de/~algorithmus/algo19.php Algorithmus der Woche - Informatikjahr 2006]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Vielleicht schon etwas älter aber doch eine gute Anleitung um eine einfache Schach-KI zu erstellen.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Link&amp;diff=25001</id>
		<title>Link</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Link&amp;diff=25001"/>
				<updated>2011-01-10T12:35:21Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Terrain */  Link zu Delphi3D entfert, Seite gibts nicht mehr&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
!!!!!!!! NUTZT DIESE TABELLE ALS VORLAGE FÜR WEITERE LINKTABELLEN !!!!!!!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[Link]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[Link]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Links die mit Grafik/OpenGL zu tun haben =&lt;br /&gt;
Hier finden Sie eine Übersicht von Links. &lt;br /&gt;
&lt;br /&gt;
*Weitere Navigations Links findet Sie unter [[DGL Wiki:Portal]]&lt;br /&gt;
*Links zu Tools oder Programmen finden Sie unter [[Tool]]s&lt;br /&gt;
&lt;br /&gt;
== Hardwareinfos ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://delphi3d.net/hardware/listreports.php OpenGL Hardware Registry - Hardwareübersicht]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Datenbank aller Grafikkarten die in der Harware Registry vorhanden sind. Die einzelnen Artikel enthalten Infos darüber, welche Extensions von der Grafikkarte unterstützt werden.&lt;br /&gt;
|-&lt;br /&gt;
|[http://delphi3d.net/hardware/allexts.php OpenGL Hardware Registry - Extensionübersicht]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Datenbank aller Extensions die in der Harware Registry vorhanden sind. Die einzelnen Artikel enthalten Infos darüber, welche Grafikkarten die entsprechende Extension unterstützen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
||[[Tutorial|DGL Wiki - Tutorial]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|DelphiGL.com ist Betreiber dieses Wikis und stellt eine Vielzahl Tutorials mit Schwehrpunkt OpenGL zur Verfügung. &lt;br /&gt;
Neben Tutorials für Einsteiger und OpenGL Anfänger gibt es auch fortgeschrittene Themen wie Shader oder Partikelsysteme.Sprache der Wahl ist hier Delphi.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.joachimrohde.com/cms/xoops/modules/articles/index.php?cat_id=1 joachimrohde.com]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet ihr deutsche Übersetzungen der bekannten NeHe Tutorials. Sprache der Wahl ist hier C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.cg.tuwien.ac.at/studentwork/VRSem96/OpenGL/ Technische Universität Wien]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://nehe.gamedev.net/ Nehe] &lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die berühmt berüchtigten NeHe Tutorials sind eine umfangreiche Sammlung an Tutorials zum Thema OpenGL. Von Anfängertutorials bis hin zu komplexen Effekten wird alles behandelt. Sprache der Wahl ist hier C++. (Eine Übersetzung der NeHe Tutorials findet ihr bei Joachim Rhode (siehe oben). )&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.sulaco.co.za/tut.htm sulaco.co.za] &lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| OpenGL Beispiele in Delphi&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Textur Erstellung ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://3d.diehlsworld.de/textures/index.htm 3d.diehlsworld.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet ihr kurze aber inhaltlich reiche Tutorials zu der Frage &amp;quot;Wie erstelle ich XXXXX-Texturen&amp;quot;. Dabei reicht die Palette von Untergrundtexturen wie Gras, Sand , Fels und Wasser (und Kombinationen dieser) bis hin zu Blitzen und Partikeln. Als Programm wird hier Photoshop verwendet.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gimps.de/gimp/textur-muster/ gimps.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Schritt für Schritt Anleitungen wie man mit Gimp verschiedene Texturen erstellt.&lt;br /&gt;
|-&lt;br /&gt;
|[http://cbt.k090999.de/gimp.php#texturen k090999.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Gimptutorials zum Erstellen verschiedene Texturen.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Blender ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://blendpolis.de/f/viewtopic.php?t=5786 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Ein Thread im Forum von [http://blendpolis.de Blendpolis] in dem '''sehr''' viele Tutorials aufgelistet sind&lt;br /&gt;
|-&lt;br /&gt;
|[http://blendpolis.de/f/article_cat.php?fldAuto=7 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Eigentliche Tutorial Seite von [http://blendpolis.de Blendpolis] die Auswahl ist hier aber nicht so groß&lt;br /&gt;
|-&lt;br /&gt;
|[http://wikivid.com/index.php/Blender Blender at wikivid.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Linksammlung von Blender Video Tutorials&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.blender.org/education-help/tutorials/getting-started/ blender3d.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Auch die Heimatseite von Blender bietet viele Tutorials unter anderm auch Video Tuorials&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.Blenderunderground.com Blenderunderground]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| '''sehr gute''' Video-Tutorials&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== OpenGL Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== GL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GL|DGL Wiki - Kategorie GL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten OpenGL Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL.tar.gz OpenGL.org - Orginal Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die Orginalspezifikationen der OpenGL 1.0 und OpenGL 1.1 Befehle. (Diese HTML-Dokumente sind nicht Copy&amp;amp;Paste freundlich, da sie vermutlich automatisch aus vorhandenen Dateien (Postscript) erzeugt wurden.)&lt;br /&gt;
|-&lt;br /&gt;
|[http://developer.3dlabs.com/documents/glmanpage_index.htm 3dLabs]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die Orginalspezifikationen der OpenGL 1.0 und OpenGL 1.1 Befehle.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von Englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc01_4f03.asp MSDN von Microsoft]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|OpenGL Dokumentation in der MSDN. Die Erklärung der MSDN sind meist keine reinen Kopien der Orginalspezifikationen, sondern enthalten hin und wieder auch zusätzliche Informationen, oder formulieren Texte auf verständlichere Art und Weise.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLU ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GLU|DGL Wiki - Kategorie GLU]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten GLU Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/ OpenGL.org - Orginal Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Orginalspezifikationen für die GLU Befehle. (Diese HTML-Dokumente sind nicht Copy&amp;amp;Paste freundlich, da sie vermutlich automatisch aus vorhandenen Dateien (Postscript) erzeugt wurden.)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glufnc01_0e43.asp MSDN von Microsoft]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|GLU Dokumentation in der MSDN. Die Erklärung der MSDN sind meist keine reinen Kopien der Orginalspezifikationen, sondern enthalten hin und wieder auch zusätzliche Informationen, oder formulieren Texte auf verständlichere Art und Weise.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLX ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:GLX|DGL Wiki - Kategorie GLX]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Wiki-Kategorie die alle übersetzten GLX Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glx/ OpenGL.org - Orginal  Spezifkationen]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Orgninalspezifikationen der GLX Befehle bei OpenGL.org.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mevis.de/~uwe/opengl/opengl.html mevis.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung von Englischsprachigen Spezifikationen für GL(bis Version 1.1), GLX und GLU Funktionen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== WGL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:WGL|DGL Wiki - Kategorie WGL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Wiki-Kategorie die alle übersetzten WGL Befehle enthält.&lt;br /&gt;
|-&lt;br /&gt;
|[http://developer.3dlabs.com/documents/wglmanpage_index.htm 3dLabs]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Sammlung einiger WGL Befehlsspezifikationen.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GLUT ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://freeglut.sourceforge.net/docs/api.php The freeglut Projekt]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Englischsprachige Dokumentation zum OpenGL Utility Toolkit kurz GLUT.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SDL ===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[:Kategorie:SDL|DGL Wiki - Kategorie SDL]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Übersicht aller auf die SDL bezogenen Artikel hier im Wiki. Darunter befinden sich eine Vielzahl von Übersetzungen der SDL Befehlspezifikationen. Diese können auch in der [[SDL-Funktionsübersicht]] gefunden werden.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.libsdl.org/cgi/docwiki.cgi/SDL_20API libsdl.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Das Dokumentationswiki von libSDL.org enthält die komplette Dokumenation zur SDL in englischer Sprache.&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.fp.sdl.de.vu/ fp.sdl.de.vu]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Eine Webseite die speziell Informationen über die Programmierung von SDL unter Freepascal zur Verfügung stellt.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAQs ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[FAQ| DGL Wiki - FAQ]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Ein FAQ (Frequently Asked Questions = Häufig gestellte Fragen) zu DelphiGL.com und dem DGL Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dsource.de/faq/index.htm 3dsource.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Ein FAQ zu Fragen rund um OpenGL.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Effekte und Techniken mit OpenGL ==&lt;br /&gt;
&lt;br /&gt;
===Glow===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamasutra.com/view/feature/2107/realtime_glow.php Gamasutra]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt, wie man mit Hilfe von Shader(hier DirectX Shader) den Gloweffekt in Realtime umsetzt. Dabei wird erst die Technik dahinter erklährt, und dann wie man sie Schritt für Schritt umsetzt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://collective.valve-erc.com/index.php?go=tron1 valve-erc.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Schritt für Schritt Anleitung, wie man mit Hilfe von Cg in OpenGL den Glow Effekt realisieren kann &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===HDR===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/columns/hardcore/hdrrendering/ gamedev.net]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Hier wird sehr kurz eingeleitet, was HDR Rendering überhaupt ist, dann wird der Aufbau des *.hdr Formats erläutert, und dann geht es schon von 0 auf 100 zum Programmieren. Erklährungen gibt es kaum, dafür werden fertige Shader(für DirectX) geboten. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/reference/articles/article2208.asp gamedev.net]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt auch nur etwas kurz das HDR Verfahren, jedoch mit mehr mathematischen Hintergrund in Sachen Tonemapping. Beispielcode für Tonemapping in C++ liegt bei. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===BSP Bäume===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dtechdev.com/tutorials/leafbsp/3dbsptrees.html 3dtechdev.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Das beste Dokument überhaupt, für allem die selber BSP Bäume compilieren möchte. Ist belegt mit sehr viel Grafik. Erst beginnt er das Prinzip allgemein zum umschreiben, dann wird alles genau erläutert, und mit verständlichen Pseudocode untermalt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dtechdev.com/tutorials/illegalgeometry/illegalgeometrytut.html 3dtechdev.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Nicht ganz so gut geworden, wie sein erstes Tutorial, aber erklährt auch sehr gut, wie man illegale Geometrie aufspürt und beseitigt. Wieder mit Grafiken und Pseudocodes verständlich belegt. Hiermit kann man seinem Map-Compiler den letzten Schliff verleien. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/reference/articles/article981.asp Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Von Michael Abrash, dürfte der ''Erfinder'' von Quake sein. Naja, meine Englischkenntnisse reichen hier nicht ganz aus, um den Text zu verstehen. Ist etwas umständlich geschrieben. Dafür mit Grafiken unterlegt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.zfx-online.de/Tutorials.php?ID=11 Part 1 - Allgemein]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Einzigste deutsche Referenz zu BSP Bäumen, dafür Daumen hoch. Ist aber nicht das Wahre: schlechter C Code, und ich hatte auch nicht den Einduck, das er die Theorie zu diesem Thema bis in die Tiefe verstanden hat(oder er wollte es nicht zu akademisch Erklähren oO). Aber ein guter Einstieg in dieses Thema. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.zfx-online.de/Tutorials.php?ID=13 Part 2 - Kollision und PVS]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.cs.uwec.edu/~stevende/cs455/programs/GameTutorials%20-%20Quake%203%20BSP%20Format.htm Quake3 *.bsp Format]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Die beste Dokumentation für das BSP Format, die ich gefunden habe, besser als den Quake3 Sourcecode zu durchforsten. Leider etwas magere Eklährung zu wichtigen Themen wie Patches(Curved Surfaces). Ich pers. hatte jetzt 1 1/2 Wochen gebraucht, um das *.bsp Format vollständig zu verstehen. Ist aber anscheinend die beste Format Dokumentation im Netz. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_q2bsp.shtml Quake2 *.bsp Format]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Kann auch nur soviel sagen, wie beim Link zuvor. Es fehlen hier auch zum Teil Informationen. Man muss halt viel ausprobieren, und sich den Quake 2 Source zu Herzen nehmen, damit man es versteht. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Himmel &amp;amp; Wolken===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/community/forums/topic.asp?topic_id=86024 Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Guter Thread mit vielen Anregungen und Links. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.gamedev.net/community/forums/topic.asp?topic_id=135654 Gamedev]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Hier wird die Diskussion zum obigen Link weitergeführt. &lt;br /&gt;
|-&lt;br /&gt;
|[http://freespace.virgin.net/hugo.elias/models/m_clouds.htm Plasma]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine nette Idee um Plasma in Echtzeit zu generieren, und zu verändern. Leider nichts zum Shading. &lt;br /&gt;
|-&lt;br /&gt;
|[http://nis-lab.is.s.u-tokyo.ac.jp/~nis/cdrom/sig00_cloud.pdf 3D Wolken]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Paper über generieren und rendern von 3 dimensionalen Wolken inklusive Schatten und Lichtstrahlen. Ich hab nur den Lichtstahlen-Algorithmus ausprobiert. Saulangsam aber sehr einfach zu implementieren. Einen Blick ist es auf jeden Fall wert. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.geocities.com/ngdash/whitepapers/skydomecolor.html Skydome]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Wenn man mal schnell gute Farben für seinen Skydome braucht... &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Terrain===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_geomipmaps.shtml FlipCode]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Artikel zu Geomipmaping. Zummindest hab ich es hier zum ersten mal gesehen. Und es funzt ganz gut. &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.vterrain.org Virtual Terrain Project]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Eine Seite mit Links und Artikeln zu allem, was etwas mit Terrainrendering zu tun hat.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Sonstiges===&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[[Materialsammlung]]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Sammlung von gängigen Parametern für [[glMaterial]] hier im Wiki.&lt;br /&gt;
|-&lt;br /&gt;
|[http://freespace.virgin.net/hugo.elias/radiosity/radiosity.htm Radiosity]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Erklährt sehr schön die Funktionsweise von Radiosity, liefert Beispielcodes und ist recht gut illustriert.&lt;br /&gt;
|-&lt;br /&gt;
|[http://legion.gibbering.net/projectx/paper/shadow%20mapping/ Shadowmapping]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Beschreibt das Trapezoidal Shadow Mapping - Verfahren für gerichte Lichter.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.flipcode.com/articles/article_generatingnames.shtml Namensgenerator]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Per Zufallsgenrator Namen erzeugen, und nie wieder kreativ werden müssen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.paulsprojects.net/tutorials/simplebump/simplebump.html Bumpmapping]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Bumpmapping auf Lowend-Grakas. Damals war Bumpmapping noch was ganz tolles... &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.paulsprojects.net/opengl/dpreflect/dpreflect.html Dot Product Reflect]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|zwar nur ne Demo, aber wenn man schon immer mal mit EMBM das Wasser aus Morrowind nachproggen wollte... &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beispiele/Demos mit Quelltext ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.delphigl.de DelphiGL.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier finden sich besonders eindrucksvolle Newton Physik Demos. Meißtens sogar mit Quelltext.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.shadow3d.de.vu/ Shadow 3D]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier finden sich zwei Demos wie man Quake 3 Modelle lädt und eine glSlang Demo&lt;br /&gt;
|-&lt;br /&gt;
|[[Shadersammlung]] im DGL Wiki&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Hier findet man freie Shadersourcen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.humus.ca Humus]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Diverse eindrucksvolle Demos zu verschiedenen Techniken, häufig mit Quelltext in C  &lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== weitere Links ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www-user.tu-chemnitz.de/~pester/Lehre/CompGeo.pdf CompGeo.pdf]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Script &amp;quot;Einführung in die Computergeometrie&amp;quot; von Dr. Pester (TU-Chemnitz). Ideales Nachschlagewerk für die Mathematik die einem bei der Grafikprogrammierung so begegnet.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.robsite.de/ robsite.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Auf dieser riesigen Seite finden sich auch viele weitere Links über verschiedene Themen der 3D Programmierung.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.3dlinks.com/links.cfm?categoryid=3&amp;amp;subcategoryid=21 3dlinks.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Diese Seite hat es sich zur Hauptaufgabe gemacht Links auf Seiten mit dem Thema 3D zu sammeln.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.two-kings.de/links.html two-kings.de]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Sammlung diverser interessanter Links, vorallem auf Themen im gamedev-Forum verweisend.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.delgine.com Delgine.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Heimat des freien 3D Modellers &amp;quot;DeleD&amp;quot;, welcher in Delphi programmiert ist. Ihr findet dort auch Modellpackete, Texturpackete, Plugins und Hilfe bei der Programmierung von Delphi und OpenGL.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Links zum Thema Spieleprogrammierung=&lt;br /&gt;
&lt;br /&gt;
==Allgemein==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.spieleprogrammierung.net/ Spieleprogrammierung - OpenGL - GLSL - OpenAL - KI - Animation - Spielephysik]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet Ihr Artikel, Tutorials und Programmbeispiele rund um das Thema Spieleprogrammierung. Programmiersprache ist hier C/C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://audio-framework.spieleprogrammierung.net/ OpenAL Audio Framework]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Auf dieser Seite findet Ihr ein frei verfügbares OpenAL Audio Framework (LGPL-Lizenz) samt zugehöriger Probammbeispiele. Unterstützt werden 3D Sounds, EFX (EAX Alternative) Reverb Effekte sowie Audio Streaming (Music and Voices). Programmiersprache ist hier C/C++.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Kopierschutz==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://inner-smile.com/nocrack.phtml Inner-Smile.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Seite mit Gedanken zum Thema &amp;quot;Wie schütze ich meine Programme vor Crackern&amp;quot;. Falls die Seite nicht erreichbar ist hat Google noch ne [http://www.google.com/search?q=cache:hpqPT5G4WB0J:www.inner-smile.com/nocrack.phtml+http://inner-smile.com/nocrack.phtml&amp;amp;hl=de&amp;amp;gl=de&amp;amp;ct=clnk&amp;amp;cd=1 Version im Archiv].&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==KI==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| width = &amp;quot;100%&amp;quot; {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;|Link&lt;br /&gt;
!width=&amp;quot;5%&amp;quot;|Sprache&lt;br /&gt;
!width=&amp;quot;70%&amp;quot;|Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.kbs.uni-hannover.de/Lehre/KI2/Presentationen/presentation9798/esprit/spieltheorie/spieltheorie.html Uni-Hannover - Spieltheorie]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Artikel über die Grundlagen von KI in Spielen.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.robsite.de/tutorials.php?tut=ki Robsite KI-Tutorials]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Sammlung von Texten zum Thema KI in Spielen. Beispiele sind meist in C++.&lt;br /&gt;
|-&lt;br /&gt;
|[http://ai-depot.com/ AI-Depot.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
| Seite die sich ausschließlich mit KI in Spielen beschäftigt.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.ai-junkie.com/links.html AI-Junkie.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Linkseite mit vielen KI relevanten Links. Die Seite AI-Junie selbst behandelt auch viele Themen rund um KI.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.aiwisdom.com/ AIWisdom.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Seite die sich mit KIs in Spielen beschäftigt und sich zum Ziel gesetzt hat, alle Artikel zum Thema zu finden und zu Katalogisieren. Es gibt hier auch Artikel über die KIs bestehender Spiele.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.aiguru.com/ AIGuru.com]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Newsseite zum Thema KI, Künstliches Leben, Hiernforschung, Robotik, Nanotechnologie - Halt alles was Spass macht.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.generation5.org/ Generation5.org]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Seite über KI, Robotik, etc. . Leider scheint die Seite Probleme zu haben regelmäßig aktualisiert zu werden. Aber zumindest sollte man einige Artikel finden. Die werden ja nicht schlecht.&lt;br /&gt;
|-&lt;br /&gt;
|www.gameai.com&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|''Wurde Januar 2010 als down gemeldet. Weiss irgendwer etwas genaueres?'' Seite zum Thema KI in Spielen. Soll wohl einen gewissen Stellenwert in der AI-Szene haben.&lt;br /&gt;
|-&lt;br /&gt;
|[http://www-i1.informatik.rwth-aachen.de/~algorithmus/algo19.php Algorithmus der Woche - Informatikjahr 2006]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Vielleicht schon etwas älter aber doch eine gute Anleitung um eine einfache Schach-KI zu erstellen.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=24975</id>
		<title>dglOpenGL.pas/en</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas/en&amp;diff=24975"/>
				<updated>2010-10-09T08:52:43Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Download */  Versionsinfo für Download korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung| '''Delphi is already shipping with an OpenGL header, but that header is ''outdated and also buggy''. Therefore we ''urge everyone to NOT use that header, especially as it lacks most of OpenGL's current functionality.'''''}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;[[Bild:Flag_german.gif]][[dglOpenGL.pas| Gehe zur deutschen Version dieser Seite ]][[Bild:Flag_german.gif]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=The DelphiGL header=&lt;br /&gt;
So to compensate for the flaws of the outdated and buggy default header that is shipped with Delphi, the [http://www.delphigl.com (german) Delphi OpenGL Community] is providing it's own header that's permanently updated to provide steady support for new OpenGL features and functionality. This makes updating to a new header version easily (usually backwards compatibility is preserved), and it's even possible to use the header with other pascal compilers like Freepascal.&lt;br /&gt;
&lt;br /&gt;
It includes all OpenGL functions (currently up-to and including OpenGL 3.0) as well as all GLU ('''OpenGL Utility Libary''') functions and supports all ARB, EXT, NV and ATI extensions. It also includes additional, though lesser common extensions from other vendors like Apple, HP and SGI.&lt;br /&gt;
&lt;br /&gt;
A special feature of this header are boolean variables for each included extensions that are flagged upon initialisation (those boolean vars carry the same as their corresponding extensions), so you can quickly check wether an extension is support or not (instead of checking the strings returned by [[glGetString/en]]).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Licence/Terms of use==&lt;br /&gt;
The '''dglOpenGL.pas''' is distributed unter the terms and conditions of the '''Mozilla Public License Version 1.1'''. You can grab a copy of that licence [http://www.mozilla.org/MPL/MPL-1.1.html here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;The contents of the dglOpenGL.pas are used with permission, subject to&amp;lt;br&amp;gt;&lt;br /&gt;
the Mozilla Public License Version 1.1 (the &amp;quot;License&amp;quot;); you may&amp;lt;br&amp;gt;&lt;br /&gt;
not use this file except in compliance with the License. You may&amp;lt;br&amp;gt;&lt;br /&gt;
obtain a copy of the License at&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mozilla.org/MPL/MPL-1.1.html&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Software distributed under the License is distributed on an&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;AS IS&amp;quot; basis, WITHOUT WARRANTY OF ANY KIND, either express or&amp;lt;br&amp;gt;&lt;br /&gt;
implied. See the License for the specific language governing&amp;lt;br&amp;gt;&lt;br /&gt;
rights and limitations under the License.&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.NET support==&lt;br /&gt;
Due to lack of interest, .NET support has been removed as of header version 2.1!&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|The .Net header won't be developed any further, but reported errors may be fixed. So new OpenGL functionality can only be found in the normal header.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Initializing function pointers (crucial)==&lt;br /&gt;
Along with the removal of .NET support, support for loading methods dynamically has also been removed and is no longer possible with the standard header. So it's crucial to call either '''AtivateRenderingContext''' or '''ReadExtensions''' alongside with '''ReadImplementationProperties''' in your application before accessing any of the OpenGL functions. Otherwise you'll likely be prompted with an access violation at address 0x00000000. &lt;br /&gt;
&lt;br /&gt;
''So if you get such an access violation please check if you called the above functions!''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''initializing''' the OpenGL function pointers (''needs to be called before you access any OpenGL functions'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLInit;&lt;br /&gt;
 begin&lt;br /&gt;
 InitOpenGL; // Don't forget, or first gl-Call will result in an access violation!&lt;br /&gt;
 MyDC := GetDC(...);&lt;br /&gt;
 MyRC := CreateRenderingContext(...);&lt;br /&gt;
 ActivateRenderingContext(MyDC, MyRC); // Necessary, will also load function pointers for all extension&lt;br /&gt;
 ...&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example for '''finishing''' the OpenGL render context (''should be called before quitting your application'') :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;procedure OpenGLFinish;&lt;br /&gt;
 begin&lt;br /&gt;
 DeactivateRenderingContext; // Deactivates the current context&lt;br /&gt;
 wglDeleteContext(myRC);&lt;br /&gt;
 ReleaseDC(Handle, myDC);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Download==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL|text=Current dglOpenGL.pas}} (Supports ''OpenGL 4.0'', works with Delphi 4 and up and Freepascal))'''&lt;br /&gt;
&lt;br /&gt;
'''{{ArchivLink|file=dglOpenGL_net|text=Last dglOpenGL.pas wit .NET support}} (Supports ''OpenGL 2.1'')'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''For Delphi 3 users :'''&lt;br /&gt;
''[[Benutzer:Mars|Mars]] has posted a version of the dglOpenGL.pas that will work with Delphi 3, you can get it here :&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas for Delphi 3] &amp;lt;br&amp;gt;&lt;br /&gt;
''(You need to be registered on the forums to download it)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''There is also an inofficial version of this [http://www.delphigl.com/forum/viewtopic.php?t=4216 headers for C++].''&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{dglOpenGL_History}}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24823</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24823"/>
				<updated>2010-04-19T09:55:11Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Die Zukunft */ aktualisiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Einleitung=&lt;br /&gt;
Hallo und willkommen bei meiner &amp;quot;Einführung&amp;quot; in GLSL (kurz für &amp;quot;Open'''GL''' '''S'''hading '''L'''anguage&amp;quot;), der offiziellen Hochlevel-Shadersprache von OpenGL. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von GLSL angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von Khronoes veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
=Was ist GLSL?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei GLSL um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in GLSL geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Eckpunkte (VertexShader), Fragmente (FragmentShader) angewendet, oder (neuerdings, ab Shadermodell 4.0) auch genutzt um Geometrie zu erstellen (Geometryshader). Andere Teile der Renderpipeline (z.B. die Rasterisierung) können momentan noch nicht durch Shader beeinflusst werden, was allerdings in Zukunft noch kommen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
GLSL wurde 2005 mit OpenGL 1.5 eingeführt. Während es in Sachen Treiber- und Hardwareunterstützung anfänglich noch dürftig aussah, wird man inzwischen keine Grafikkarte mehr kaufen können die nicht zumindest Vertex- und Fragmentshader beherscht. Geometrieshader hingegen sind relativ neu und wurden erst mit Shadermodell 4.0 eingeführt, hier ist es also unter Umständen noch möglich dass selbst aktuelle Treiber/Karten keine Geometrieshader beherrschen.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt man auch einen passenden OpenGL-Header der die für GLSL nötigen Funktionen exportiert. Ich verweise dazu auf unseren eigenen OpenGL-Header [[DGLOpenGL.pas]], der peermanent auf dem aktuellsten Stand gehalten wird und auch Support für Geometrieshader mitbringt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Extensions==&lt;br /&gt;
&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis''' : Seit OpenGL 2.0 ist GLSL Teil des Kerns. Wenn die Karte als OpenGL 2.0 unterstützt, dann unterstützt sie auch (zumindest in Software) Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Sprachversionen==&lt;br /&gt;
&lt;br /&gt;
Neben der OpenGL-Version und dem vorhandenen Shadermodell (das eher an DirectX ausgerichtet ist), bietet auch GLSL verschiedene Versionen, die entsprechend erweiterte Funktionalität bieten.&lt;br /&gt;
&lt;br /&gt;
Auslesen kann man die verfürgbare GLSL-Version wie folgt :&lt;br /&gt;
&lt;br /&gt;
 glGetString(GL_SHADING_LANGUAGE_VERSION)&lt;br /&gt;
&lt;br /&gt;
Erst ab Version 1.4. kann man davon ausgehen dass GLSL alle Features des Shadermodells 4.0 liefert, ab 1.3 grob gesagt Shadermodell 3.0 (bei GLSL lässt sich das leider nicht so leicht unterteilen).&lt;br /&gt;
&lt;br /&gt;
Ausserdem kann man seinem Shader eine Versionsnummer verpassen. Sollte der Shadercompiler (also Treiber bzw. Hardware) diese Version nicht unterstützen, gibt dieser eine Fehlermeldung heraus :&lt;br /&gt;
&lt;br /&gt;
 #version 1.50 &lt;br /&gt;
&lt;br /&gt;
''(Hinweis : Muss am Anfang des Shaders stehen)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER''', '''GL_FRAGMENT_SHADER_ARB''' oder '''GL_GEOMETRY_SHADER'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ressourcen==&lt;br /&gt;
&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist die [http://www.opengl.org/documentation/specs/ Spezifikationenliste auf OpenGl.ORG].&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse zum Zugriff auf Texturen dar, und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRect 	&lt;br /&gt;
|Zugriff auf Texturen die nicht 2^n * 2^n entsprechen (&amp;quot;non power-of-two&amp;quot;, NPOT)&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|samplerCubeShadow&lt;br /&gt;
|Zugriff auf Tiefentextur in einer Cubemap (z.b. für omni-diretionale Lichtquellen)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRectShadow&lt;br /&gt;
|Zugriff auf 2D-NPOT-Tiefentextur &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|sampler1DArray&lt;br /&gt;
|Zugriff auf ein array aus 1D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArray&lt;br /&gt;
|Zugriff auf ein array aus 2D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler1DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 1D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 2D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|samplerBuffer&lt;br /&gt;
|Zugriff auf eine Puffertextur (1D-Texutr zum Speichern von Pufferobjekten)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMS&lt;br /&gt;
|Zugriff auf eine 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMSArray&lt;br /&gt;
|Zugriff auf einarray aus 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispiele=&lt;br /&gt;
&lt;br /&gt;
Anbei ein paar exemplarische Screenshots. Da man mit GLSL aber alle möglichen Effekte berechnen kann (u.a. auch 1:1 die feste Funktionspipeline) ist es hier unmöglich einen Überblick aller möglichen Techniken zu geben.&lt;br /&gt;
&lt;br /&gt;
[[Datei:tut_glsl_eigenershader_01.png]] [[Datei:tut_glsl_eigenershader_02.png]] [[Datei:tut_glsl_eigenershader_03.png]]&lt;br /&gt;
&lt;br /&gt;
Wie im ersten (und dritten) Screenshot zu sehen ist es natürlich auch möglich mehrere Techniken innerhalb einer Szene zu nutzen. Hier sind letztendlich bis auf Hardwarelimitationen keine Grenzen gesetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Als dieses Tutorial geschrieben wurde, war noch nicht ganz abzusehen dass bzw. ob sich GLSL auch durchsetzen würde. ARB-Shadr und NVidias cG waren damals die Platzhirsche, aber inzwischen werden ARB-Shader nicht mehr genutzt (und auch schon länger nicht mehr weiterentwickelt) und auch NVidia setzt primär auf GLSL. GLSL wird permanent weiterenwtickelt und Hersteller können dank des flexiblen Extensionsystems auch in GLSL eigene Extensions offenlegen um die aktuellsten Features (wie z.b. den Tesselator auf aktuellen ATI-Karten) nutzen zu können. GLSL it als inzwischen auch offizielle die Shadersprache frü OpenGL und wird permanent an die neusten technischen Entwicklungen im Grafikkartenbereich angepasst.&lt;br /&gt;
&lt;br /&gt;
Wer also unter OpenGL etwas mit Shadern machen möchte, kommt an GLSL nicht vorbei!&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24822</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24822"/>
				<updated>2010-04-19T09:37:31Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Screenshots */  eigene Bilder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Einleitung=&lt;br /&gt;
Hallo und willkommen bei meiner &amp;quot;Einführung&amp;quot; in GLSL (kurz für &amp;quot;Open'''GL''' '''S'''hading '''L'''anguage&amp;quot;), der offiziellen Hochlevel-Shadersprache von OpenGL. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von GLSL angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von Khronoes veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
=Was ist GLSL?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei GLSL um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in GLSL geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Eckpunkte (VertexShader), Fragmente (FragmentShader) angewendet, oder (neuerdings, ab Shadermodell 4.0) auch genutzt um Geometrie zu erstellen (Geometryshader). Andere Teile der Renderpipeline (z.B. die Rasterisierung) können momentan noch nicht durch Shader beeinflusst werden, was allerdings in Zukunft noch kommen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
GLSL wurde 2005 mit OpenGL 1.5 eingeführt. Während es in Sachen Treiber- und Hardwareunterstützung anfänglich noch dürftig aussah, wird man inzwischen keine Grafikkarte mehr kaufen können die nicht zumindest Vertex- und Fragmentshader beherscht. Geometrieshader hingegen sind relativ neu und wurden erst mit Shadermodell 4.0 eingeführt, hier ist es also unter Umständen noch möglich dass selbst aktuelle Treiber/Karten keine Geometrieshader beherrschen.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt man auch einen passenden OpenGL-Header der die für GLSL nötigen Funktionen exportiert. Ich verweise dazu auf unseren eigenen OpenGL-Header [[DGLOpenGL.pas]], der peermanent auf dem aktuellsten Stand gehalten wird und auch Support für Geometrieshader mitbringt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Extensions==&lt;br /&gt;
&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis''' : Seit OpenGL 2.0 ist GLSL Teil des Kerns. Wenn die Karte als OpenGL 2.0 unterstützt, dann unterstützt sie auch (zumindest in Software) Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Sprachversionen==&lt;br /&gt;
&lt;br /&gt;
Neben der OpenGL-Version und dem vorhandenen Shadermodell (das eher an DirectX ausgerichtet ist), bietet auch GLSL verschiedene Versionen, die entsprechend erweiterte Funktionalität bieten.&lt;br /&gt;
&lt;br /&gt;
Auslesen kann man die verfürgbare GLSL-Version wie folgt :&lt;br /&gt;
&lt;br /&gt;
 glGetString(GL_SHADING_LANGUAGE_VERSION)&lt;br /&gt;
&lt;br /&gt;
Erst ab Version 1.4. kann man davon ausgehen dass GLSL alle Features des Shadermodells 4.0 liefert, ab 1.3 grob gesagt Shadermodell 3.0 (bei GLSL lässt sich das leider nicht so leicht unterteilen).&lt;br /&gt;
&lt;br /&gt;
Ausserdem kann man seinem Shader eine Versionsnummer verpassen. Sollte der Shadercompiler (also Treiber bzw. Hardware) diese Version nicht unterstützen, gibt dieser eine Fehlermeldung heraus :&lt;br /&gt;
&lt;br /&gt;
 #version 1.50 &lt;br /&gt;
&lt;br /&gt;
''(Hinweis : Muss am Anfang des Shaders stehen)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER''', '''GL_FRAGMENT_SHADER_ARB''' oder '''GL_GEOMETRY_SHADER'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ressourcen==&lt;br /&gt;
&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist die [http://www.opengl.org/documentation/specs/ Spezifikationenliste auf OpenGl.ORG].&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse zum Zugriff auf Texturen dar, und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRect 	&lt;br /&gt;
|Zugriff auf Texturen die nicht 2^n * 2^n entsprechen (&amp;quot;non power-of-two&amp;quot;, NPOT)&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|samplerCubeShadow&lt;br /&gt;
|Zugriff auf Tiefentextur in einer Cubemap (z.b. für omni-diretionale Lichtquellen)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRectShadow&lt;br /&gt;
|Zugriff auf 2D-NPOT-Tiefentextur &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|sampler1DArray&lt;br /&gt;
|Zugriff auf ein array aus 1D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArray&lt;br /&gt;
|Zugriff auf ein array aus 2D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler1DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 1D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 2D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|samplerBuffer&lt;br /&gt;
|Zugriff auf eine Puffertextur (1D-Texutr zum Speichern von Pufferobjekten)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMS&lt;br /&gt;
|Zugriff auf eine 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMSArray&lt;br /&gt;
|Zugriff auf einarray aus 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispiele=&lt;br /&gt;
&lt;br /&gt;
Anbei ein paar exemplarische Screenshots. Da man mit GLSL aber alle möglichen Effekte berechnen kann (u.a. auch 1:1 die feste Funktionspipeline) ist es hier unmöglich einen Überblick aller möglichen Techniken zu geben.&lt;br /&gt;
&lt;br /&gt;
[[Datei:tut_glsl_eigenershader_01.png]] [[Datei:tut_glsl_eigenershader_02.png]] [[Datei:tut_glsl_eigenershader_03.png]]&lt;br /&gt;
&lt;br /&gt;
Wie im ersten (und dritten) Screenshot zu sehen ist es natürlich auch möglich mehrere Techniken innerhalb einer Szene zu nutzen. Hier sind letztendlich bis auf Hardwarelimitationen keine Grenzen gesetzt.&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Viele werden sich sicherlich fragen, warum sie z.B. statt ARB_VP/FP oder Nvidias cG denn überhaupt auf glSlang setzen sollen. Doch solche Zweifel dürften bei einem genauen Blick auf die neue Shadersprache schnell verworfen sein. Zum einen steckt hinter glSlang dank des ARBs fast die komplette 3D-Industrie und zum anderen hat man beim Entwurf der Shadersprache, wie z.B. an vielen reservierten Wörtern/Funktionen erkennbar versucht so weit wie möglich in die Zukunft zu planen. So sollen auch Karten der nächsten und übernächsten Generation mit glSlang ausnutzbar sein, und was danach kommt wird durch Spracherweiterungen erreicht. Sich also jetzt (besonders da es krachneu ist) mit glSlang zu befassen, um nicht ganz den Anschluss an kommende Entwicklungen im 3D-Bereich zu verlieren, ist der beste Weg.&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_03.png&amp;diff=24821</id>
		<title>Datei:tut glsl eigenershader 03.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_03.png&amp;diff=24821"/>
				<updated>2010-04-19T09:37:05Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Eigener Shader aus einem alten Projekt. Hier sind die Schatten mittels fester Funktionspipeline über Stencilvolumen realisiert. Die Kugel in der Mitte wird via Shader und Cubemap als reflektierend dargestellt, an der Decke ein Pointlight und rundherum le&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eigener Shader aus einem alten Projekt. Hier sind die Schatten mittels fester Funktionspipeline über Stencilvolumen realisiert. Die Kugel in der Mitte wird via Shader und Cubemap als reflektierend dargestellt, an der Decke ein Pointlight und rundherum leichtes parallax mapping.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_02.png&amp;diff=24820</id>
		<title>Datei:tut glsl eigenershader 02.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_02.png&amp;diff=24820"/>
				<updated>2010-04-19T09:29:49Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Eigener Shader mit simulierter Wasseroberfläche. Nutzt hier eine Cubemap zur Errechnung der Spiegelung.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eigener Shader mit simulierter Wasseroberfläche. Nutzt hier eine Cubemap zur Errechnung der Spiegelung.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_01.png&amp;diff=24819</id>
		<title>Datei:tut glsl eigenershader 01.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:tut_glsl_eigenershader_01.png&amp;diff=24819"/>
				<updated>2010-04-19T09:29:08Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Kombination mehrerer Shader. Parallax Offset Mapping an Wand, Boden und Decke und ein eigener Shader zu Errechnung der Schatten auf Basis einer Entfernungswertecubemap.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kombination mehrerer Shader. Parallax Offset Mapping an Wand, Boden und Decke und ein eigener Shader zu Errechnung der Schatten auf Basis einer Entfernungswertecubemap.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24818</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24818"/>
				<updated>2010-04-16T10:38:21Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Präambel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Einleitung=&lt;br /&gt;
Hallo und willkommen bei meiner &amp;quot;Einführung&amp;quot; in GLSL (kurz für &amp;quot;Open'''GL''' '''S'''hading '''L'''anguage&amp;quot;), der offiziellen Hochlevel-Shadersprache von OpenGL. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von GLSL angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von Khronoes veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
=Was ist GLSL?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei GLSL um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in GLSL geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Eckpunkte (VertexShader), Fragmente (FragmentShader) angewendet, oder (neuerdings, ab Shadermodell 4.0) auch genutzt um Geometrie zu erstellen (Geometryshader). Andere Teile der Renderpipeline (z.B. die Rasterisierung) können momentan noch nicht durch Shader beeinflusst werden, was allerdings in Zukunft noch kommen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
GLSL wurde 2005 mit OpenGL 1.5 eingeführt. Während es in Sachen Treiber- und Hardwareunterstützung anfänglich noch dürftig aussah, wird man inzwischen keine Grafikkarte mehr kaufen können die nicht zumindest Vertex- und Fragmentshader beherscht. Geometrieshader hingegen sind relativ neu und wurden erst mit Shadermodell 4.0 eingeführt, hier ist es also unter Umständen noch möglich dass selbst aktuelle Treiber/Karten keine Geometrieshader beherrschen.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt man auch einen passenden OpenGL-Header der die für GLSL nötigen Funktionen exportiert. Ich verweise dazu auf unseren eigenen OpenGL-Header [[DGLOpenGL.pas]], der peermanent auf dem aktuellsten Stand gehalten wird und auch Support für Geometrieshader mitbringt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Extensions==&lt;br /&gt;
&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis''' : Seit OpenGL 2.0 ist GLSL Teil des Kerns. Wenn die Karte als OpenGL 2.0 unterstützt, dann unterstützt sie auch (zumindest in Software) Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Sprachversionen==&lt;br /&gt;
&lt;br /&gt;
Neben der OpenGL-Version und dem vorhandenen Shadermodell (das eher an DirectX ausgerichtet ist), bietet auch GLSL verschiedene Versionen, die entsprechend erweiterte Funktionalität bieten.&lt;br /&gt;
&lt;br /&gt;
Auslesen kann man die verfürgbare GLSL-Version wie folgt :&lt;br /&gt;
&lt;br /&gt;
 glGetString(GL_SHADING_LANGUAGE_VERSION)&lt;br /&gt;
&lt;br /&gt;
Erst ab Version 1.4. kann man davon ausgehen dass GLSL alle Features des Shadermodells 4.0 liefert, ab 1.3 grob gesagt Shadermodell 3.0 (bei GLSL lässt sich das leider nicht so leicht unterteilen).&lt;br /&gt;
&lt;br /&gt;
Ausserdem kann man seinem Shader eine Versionsnummer verpassen. Sollte der Shadercompiler (also Treiber bzw. Hardware) diese Version nicht unterstützen, gibt dieser eine Fehlermeldung heraus :&lt;br /&gt;
&lt;br /&gt;
 #version 1.50 &lt;br /&gt;
&lt;br /&gt;
''(Hinweis : Muss am Anfang des Shaders stehen)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER''', '''GL_FRAGMENT_SHADER_ARB''' oder '''GL_GEOMETRY_SHADER'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ressourcen==&lt;br /&gt;
&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist die [http://www.opengl.org/documentation/specs/ Spezifikationenliste auf OpenGl.ORG].&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse zum Zugriff auf Texturen dar, und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRect 	&lt;br /&gt;
|Zugriff auf Texturen die nicht 2^n * 2^n entsprechen (&amp;quot;non power-of-two&amp;quot;, NPOT)&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|samplerCubeShadow&lt;br /&gt;
|Zugriff auf Tiefentextur in einer Cubemap (z.b. für omni-diretionale Lichtquellen)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRectShadow&lt;br /&gt;
|Zugriff auf 2D-NPOT-Tiefentextur &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|sampler1DArray&lt;br /&gt;
|Zugriff auf ein array aus 1D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArray&lt;br /&gt;
|Zugriff auf ein array aus 2D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler1DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 1D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 2D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|samplerBuffer&lt;br /&gt;
|Zugriff auf eine Puffertextur (1D-Texutr zum Speichern von Pufferobjekten)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMS&lt;br /&gt;
|Zugriff auf eine 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMSArray&lt;br /&gt;
|Zugriff auf einarray aus 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Screenshots=&lt;br /&gt;
&lt;br /&gt;
Um eure Augen ein wenig zu verwöhnen und zu zeigen was man mit glSlang alles machen, v.a. da man jetzt Shader schön lesbar in einer Hochsprache verfassen kann, mal ein paar Screens. Besonders der zweite Shot sieht animiert noch besser aus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[BILD:GLSL_sample_Kugel.jpg]] [[BILD:GLSL_sample_Alien.jpg]] &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Zahl möglicher Effekte ist bei einer so flexiblen Shadersprache natürlich nahezu unbegrenzt, und besonders auf kommender Hardware werden bisher ungesehen Effekte den Einzu in die Echtzeitgrafik finden. Man darf also mehr als gespannt sein.&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Viele werden sich sicherlich fragen, warum sie z.B. statt ARB_VP/FP oder Nvidias cG denn überhaupt auf glSlang setzen sollen. Doch solche Zweifel dürften bei einem genauen Blick auf die neue Shadersprache schnell verworfen sein. Zum einen steckt hinter glSlang dank des ARBs fast die komplette 3D-Industrie und zum anderen hat man beim Entwurf der Shadersprache, wie z.B. an vielen reservierten Wörtern/Funktionen erkennbar versucht so weit wie möglich in die Zukunft zu planen. So sollen auch Karten der nächsten und übernächsten Generation mit glSlang ausnutzbar sein, und was danach kommt wird durch Spracherweiterungen erreicht. Sich also jetzt (besonders da es krachneu ist) mit glSlang zu befassen, um nicht ganz den Anschluss an kommende Entwicklungen im 3D-Bereich zu verlieren, ist der beste Weg.&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24817</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24817"/>
				<updated>2010-04-16T10:13:17Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Was ist glSlang? */ glslang wird heute nicht mehr benutzt, daher durch GLSL ersetzt, Ergänzungen und Info zur GLSL-Version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Präambel=&lt;br /&gt;
Ave und willkommen bei meiner &amp;quot;Einführung&amp;quot; in die recht frische und mit OpenGL1.5 eingeführte Shadersprache &amp;quot;glSlang&amp;quot;. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von glSlang angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von 3DLabs veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Was ist GLSL?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei GLSL um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in GLSL geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Eckpunkte (VertexShader), Fragmente (FragmentShader) angewendet, oder (neuerdings, ab Shadermodell 4.0) auch genutzt um Geometrie zu erstellen (Geometryshader). Andere Teile der Renderpipeline (z.B. die Rasterisierung) können momentan noch nicht durch Shader beeinflusst werden, was allerdings in Zukunft noch kommen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
GLSL wurde 2005 mit OpenGL 1.5 eingeführt. Während es in Sachen Treiber- und Hardwareunterstützung anfänglich noch dürftig aussah, wird man inzwischen keine Grafikkarte mehr kaufen können die nicht zumindest Vertex- und Fragmentshader beherscht. Geometrieshader hingegen sind relativ neu und wurden erst mit Shadermodell 4.0 eingeführt, hier ist es also unter Umständen noch möglich dass selbst aktuelle Treiber/Karten keine Geometrieshader beherrschen.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt man auch einen passenden OpenGL-Header der die für GLSL nötigen Funktionen exportiert. Ich verweise dazu auf unseren eigenen OpenGL-Header [[DGLOpenGL.pas]], der peermanent auf dem aktuellsten Stand gehalten wird und auch Support für Geometrieshader mitbringt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Extensions==&lt;br /&gt;
&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis''' : Seit OpenGL 2.0 ist GLSL Teil des Kerns. Wenn die Karte als OpenGL 2.0 unterstützt, dann unterstützt sie auch (zumindest in Software) Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Sprachversionen==&lt;br /&gt;
&lt;br /&gt;
Neben der OpenGL-Version und dem vorhandenen Shadermodell (das eher an DirectX ausgerichtet ist), bietet auch GLSL verschiedene Versionen, die entsprechend erweiterte Funktionalität bieten.&lt;br /&gt;
&lt;br /&gt;
Auslesen kann man die verfürgbare GLSL-Version wie folgt :&lt;br /&gt;
&lt;br /&gt;
 glGetString(GL_SHADING_LANGUAGE_VERSION)&lt;br /&gt;
&lt;br /&gt;
Erst ab Version 1.4. kann man davon ausgehen dass GLSL alle Features des Shadermodells 4.0 liefert, ab 1.3 grob gesagt Shadermodell 3.0 (bei GLSL lässt sich das leider nicht so leicht unterteilen).&lt;br /&gt;
&lt;br /&gt;
Ausserdem kann man seinem Shader eine Versionsnummer verpassen. Sollte der Shadercompiler (also Treiber bzw. Hardware) diese Version nicht unterstützen, gibt dieser eine Fehlermeldung heraus :&lt;br /&gt;
&lt;br /&gt;
 #version 1.50 &lt;br /&gt;
&lt;br /&gt;
''(Hinweis : Muss am Anfang des Shaders stehen)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER''', '''GL_FRAGMENT_SHADER_ARB''' oder '''GL_GEOMETRY_SHADER'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Ressourcen==&lt;br /&gt;
&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist die [http://www.opengl.org/documentation/specs/ Spezifikationenliste auf OpenGl.ORG].&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse zum Zugriff auf Texturen dar, und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRect 	&lt;br /&gt;
|Zugriff auf Texturen die nicht 2^n * 2^n entsprechen (&amp;quot;non power-of-two&amp;quot;, NPOT)&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|samplerCubeShadow&lt;br /&gt;
|Zugriff auf Tiefentextur in einer Cubemap (z.b. für omni-diretionale Lichtquellen)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRectShadow&lt;br /&gt;
|Zugriff auf 2D-NPOT-Tiefentextur &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|sampler1DArray&lt;br /&gt;
|Zugriff auf ein array aus 1D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArray&lt;br /&gt;
|Zugriff auf ein array aus 2D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler1DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 1D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 2D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|samplerBuffer&lt;br /&gt;
|Zugriff auf eine Puffertextur (1D-Texutr zum Speichern von Pufferobjekten)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMS&lt;br /&gt;
|Zugriff auf eine 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMSArray&lt;br /&gt;
|Zugriff auf einarray aus 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Screenshots=&lt;br /&gt;
&lt;br /&gt;
Um eure Augen ein wenig zu verwöhnen und zu zeigen was man mit glSlang alles machen, v.a. da man jetzt Shader schön lesbar in einer Hochsprache verfassen kann, mal ein paar Screens. Besonders der zweite Shot sieht animiert noch besser aus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[BILD:GLSL_sample_Kugel.jpg]] [[BILD:GLSL_sample_Alien.jpg]] &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Zahl möglicher Effekte ist bei einer so flexiblen Shadersprache natürlich nahezu unbegrenzt, und besonders auf kommender Hardware werden bisher ungesehen Effekte den Einzu in die Echtzeitgrafik finden. Man darf also mehr als gespannt sein.&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Viele werden sich sicherlich fragen, warum sie z.B. statt ARB_VP/FP oder Nvidias cG denn überhaupt auf glSlang setzen sollen. Doch solche Zweifel dürften bei einem genauen Blick auf die neue Shadersprache schnell verworfen sein. Zum einen steckt hinter glSlang dank des ARBs fast die komplette 3D-Industrie und zum anderen hat man beim Entwurf der Shadersprache, wie z.B. an vielen reservierten Wörtern/Funktionen erkennbar versucht so weit wie möglich in die Zukunft zu planen. So sollen auch Karten der nächsten und übernächsten Generation mit glSlang ausnutzbar sein, und was danach kommt wird durch Spracherweiterungen erreicht. Sich also jetzt (besonders da es krachneu ist) mit glSlang zu befassen, um nicht ganz den Anschluss an kommende Entwicklungen im 3D-Bereich zu verlieren, ist der beste Weg.&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24816</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24816"/>
				<updated>2010-04-16T09:52:14Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Datentypen */  um neuere Samplertypen ergänzt und Sampler in eigene Tabelle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Präambel=&lt;br /&gt;
Ave und willkommen bei meiner &amp;quot;Einführung&amp;quot; in die recht frische und mit OpenGL1.5 eingeführte Shadersprache &amp;quot;glSlang&amp;quot;. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von glSlang angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von 3DLabs veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Was ist glSlang?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei glSlang um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in glSlang geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Vertexe (VertexShader) oder Fragmente (FragmentShader) angewendet, andere noch nicht programmierbare Teile der GL-Pipeline wie z.B. die Rasterisierung können momentan noch nicht über Shader beeinflusst werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
glSlang ist ein recht neues Feature, dass mit OpenGL1.5 eingeführt wurde, weshalb eine entsprechend moderne Grafikkarte (DX9-Generation) inklusive aktuellster Treiber von Nöten ist. &lt;br /&gt;
''Aktueller Stand (November 2005) ist wie folgt :''&lt;br /&gt;
&lt;br /&gt;
[http://www.ati.com ATI] haben bereits seit fast 2 Jahren (Catalyst 3.10) glSlang-fähige Treiber, allerdings kommt es besonders mit neueren Treibern hier und da immernoch zu Fehlern (oder es werden gar neue Fehler eingführt) und ATI zeigt momentan kein sehr starkes Interesse am fixen dieser Fehler.&lt;br /&gt;
&lt;br /&gt;
[http://www.nvidia.com NVidia] haben sich etwas mehr Zeit gelassen, allerdings ist deren glSlang-Implementation inzwischen recht ausgereift. Bugs gibts allerdings trotzdem hier und da, aber NVidias Entwicklersupport ist da recht offen für Fehlerberichte. Die aktuellen Treiber der 80er Reihe sind daher für glSlang-Nutzer bestens geeignet.&lt;br /&gt;
&lt;br /&gt;
[http://www.3dlabs.com 3DLabs], die glSlang quasi erfunden haben, haben natürlich hervorragenden glSlang Support in ihren Treiber, allerdings sind deren Wildcat-Karten kaum verbreitet.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt ihr auch einen passenden OpenGL-Header der die für glSlang nötigen Extensions und Funktionen exportiert. Ich verweise dazu auf unseren internen OpenGL-Header [[DGLOpenGL.pas]] der da einwandfrei seine Dienste verrichtet und auch in der Beispielanwendung Verwendung findet.&lt;br /&gt;
&lt;br /&gt;
==Neue Extensions==&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER_ARB''' oder '''GL_FRAGMENT_SHADER_ARB'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Resourcen==&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist natürlich die [http://www.3dlabs.com/support/developer/ogl2/index.htm GL2-Seite von 3D-Labs], wo u.a. auch ein OGL2-SDK und diverse Whitepapers als PDFs angeboten werden, in denen auch stattgefundene Änderungen an glSlang dokumentiert sind.&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse zum Zugriff auf Texturen dar, und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRect 	&lt;br /&gt;
|Zugriff auf Texturen die nicht 2^n * 2^n entsprechen (&amp;quot;non power-of-two&amp;quot;, NPOT)&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|samplerCubeShadow&lt;br /&gt;
|Zugriff auf Tiefentextur in einer Cubemap (z.b. für omni-diretionale Lichtquellen)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DRectShadow&lt;br /&gt;
|Zugriff auf 2D-NPOT-Tiefentextur &lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|sampler1DArray&lt;br /&gt;
|Zugriff auf ein array aus 1D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArray&lt;br /&gt;
|Zugriff auf ein array aus 2D-Texturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler1DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 1D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|sampler2DArrayShadow&lt;br /&gt;
|Zugriff auf ein array aus 2D-Tiefentexturen &lt;br /&gt;
|-&lt;br /&gt;
|samplerBuffer&lt;br /&gt;
|Zugriff auf eine Puffertextur (1D-Texutr zum Speichern von Pufferobjekten)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMS&lt;br /&gt;
|Zugriff auf eine 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DMSArray&lt;br /&gt;
|Zugriff auf einarray aus 2D-Textur mit mehreren Samplepunkten (z.b. für Multisampling)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Screenshots=&lt;br /&gt;
&lt;br /&gt;
Um eure Augen ein wenig zu verwöhnen und zu zeigen was man mit glSlang alles machen, v.a. da man jetzt Shader schön lesbar in einer Hochsprache verfassen kann, mal ein paar Screens. Besonders der zweite Shot sieht animiert noch besser aus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[BILD:GLSL_sample_Kugel.jpg]] [[BILD:GLSL_sample_Alien.jpg]] &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Zahl möglicher Effekte ist bei einer so flexiblen Shadersprache natürlich nahezu unbegrenzt, und besonders auf kommender Hardware werden bisher ungesehen Effekte den Einzu in die Echtzeitgrafik finden. Man darf also mehr als gespannt sein.&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Viele werden sich sicherlich fragen, warum sie z.B. statt ARB_VP/FP oder Nvidias cG denn überhaupt auf glSlang setzen sollen. Doch solche Zweifel dürften bei einem genauen Blick auf die neue Shadersprache schnell verworfen sein. Zum einen steckt hinter glSlang dank des ARBs fast die komplette 3D-Industrie und zum anderen hat man beim Entwurf der Shadersprache, wie z.B. an vielen reservierten Wörtern/Funktionen erkennbar versucht so weit wie möglich in die Zukunft zu planen. So sollen auch Karten der nächsten und übernächsten Generation mit glSlang ausnutzbar sein, und was danach kommt wird durch Spracherweiterungen erreicht. Sich also jetzt (besonders da es krachneu ist) mit glSlang zu befassen, um nicht ganz den Anschluss an kommende Entwicklungen im 3D-Bereich zu verlieren, ist der beste Weg.&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24815</id>
		<title>Tutorial glsl</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_glsl&amp;diff=24815"/>
				<updated>2010-04-16T09:34:28Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* glSlang im Programm */  vom ARB zum Kern gehts hier lang...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Präambel=&lt;br /&gt;
Ave und willkommen bei meiner &amp;quot;Einführung&amp;quot; in die recht frische und mit OpenGL1.5 eingeführte Shadersprache &amp;quot;glSlang&amp;quot;. In diesem umfangreichen Dokument werde ich versuchen, sowohl auf die Nutzung (sprich das Laden und Anhängen von Shadern im Quellcode), als auch auf die Programmierung von Shadern selbst einzugehen, inklusive aller Sprachelemente der OpenGL Shadersprache. Es wird also auch recht viele Informationen zu der C-ähnlichen Programmstruktur und den von glSlang angebotenen Variablen und Attributen gehen. Am Ende dieser Einführung sollten alle die, die sich für das Thema interessieren, in der Lage sein, zumindest einfach Shader zu schreiben und auch in ihren Programmen zu nutzen. Ausserdem soll dieses Dokument gleichzeitig als ein deutsches &amp;quot;Pendant&amp;quot; zu den von 3DLabs veröffentlichten Shaderspezifikationen, und damit als alltägliches Nachschlagewerk, dienen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Wie auch schon mein ARB_VP-Tutorial richtet sich auch diese Einführung aufgrund ihrer Thematik eher an die fortgeschritteneren GL-Programmierer und neben sehr guten GL-Kenntnissen sollten sich alle, die sich daran versuchen wollen, mit den technischen Hintergründen der GL, wie z.B. dem Aufbau der Renderpipeline auskennen. Weiterhin sind C-Kenntnisse absolut erforderlich, da die Shader ja in einer an ANSI-C angelehnten Syntax geschrieben werden. Auch Begriffsdefinitionen zu Vertex oder Fragment werden zum Verständis dieser Einführung benötigt. Wer also noch am Anfang seiner GL-Karriere steht, dem wird dieses Dokument nicht viel nützen. Ganz nebenbei solltet ihr auch noch eine gehörige Portion Zeit (am besten nen kompletten Nachmittag) mitbringen, denn die folgende Kost ist nicht nur umfangreich, sondern auch manchmal recht schwer verdaulich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Was ist glSlang?=&lt;br /&gt;
Wie Eingangs kurz angesprochen handelt es sich bei glSlang um eine Shadersprache, also um eine Hochsprache, in der man die programmierbaren Teile aktueller Grafikbeschleuniger nach eigenem Belieben programmieren kann. Sie stellt quasi den Nachfolger zu den in Assembler geschriebenen Vertex- und Fragmentprogrammen ([[GL_ARB_Vertex_Program]]/[[GL_ARB_Fragment_Program]]) dar und basiert auf ANSI C, erweitert um Vektor- und Matrixtypen sowie einige C++-Mechanismen.&lt;br /&gt;
&lt;br /&gt;
Die in glSlang geschriebenen Programme nennen sich, angepasst an die Terminologie von RenderMan und DirectX, [[Shader]] (im Gegensatz zu &amp;quot;Programme&amp;quot; bei ARB_VP/FP) und werden entweder auf Vertexe (VertexShader) oder Fragmente (FragmentShader) angewendet, andere noch nicht programmierbare Teile der GL-Pipeline wie z.B. die Rasterisierung können momentan noch nicht über Shader beeinflusst werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
&lt;br /&gt;
glSlang ist ein recht neues Feature, dass mit OpenGL1.5 eingeführt wurde, weshalb eine entsprechend moderne Grafikkarte (DX9-Generation) inklusive aktuellster Treiber von Nöten ist. &lt;br /&gt;
''Aktueller Stand (November 2005) ist wie folgt :''&lt;br /&gt;
&lt;br /&gt;
[http://www.ati.com ATI] haben bereits seit fast 2 Jahren (Catalyst 3.10) glSlang-fähige Treiber, allerdings kommt es besonders mit neueren Treibern hier und da immernoch zu Fehlern (oder es werden gar neue Fehler eingführt) und ATI zeigt momentan kein sehr starkes Interesse am fixen dieser Fehler.&lt;br /&gt;
&lt;br /&gt;
[http://www.nvidia.com NVidia] haben sich etwas mehr Zeit gelassen, allerdings ist deren glSlang-Implementation inzwischen recht ausgereift. Bugs gibts allerdings trotzdem hier und da, aber NVidias Entwicklersupport ist da recht offen für Fehlerberichte. Die aktuellen Treiber der 80er Reihe sind daher für glSlang-Nutzer bestens geeignet.&lt;br /&gt;
&lt;br /&gt;
[http://www.3dlabs.com 3DLabs], die glSlang quasi erfunden haben, haben natürlich hervorragenden glSlang Support in ihren Treiber, allerdings sind deren Wildcat-Karten kaum verbreitet.&lt;br /&gt;
&lt;br /&gt;
Natürlich benötigt ihr auch einen passenden OpenGL-Header der die für glSlang nötigen Extensions und Funktionen exportiert. Ich verweise dazu auf unseren internen OpenGL-Header [[DGLOpenGL.pas]] der da einwandfrei seine Dienste verrichtet und auch in der Beispielanwendung Verwendung findet.&lt;br /&gt;
&lt;br /&gt;
==Neue Extensions==&lt;br /&gt;
Die GL-Shadersprache &amp;quot;besteht&amp;quot; in ihrer aktuellen Version aus folgenden Extensions, fürs Verständnis wäre es nicht schlecht, wenn ihr euch zumindest die Einleitungen dazu durchlest :&lt;br /&gt;
* [[GL_ARB_Shader_Objects]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shader_objects.txt Orginal Spezifikation])&lt;br /&gt;
: Definiert die API-Aufrufe die zum Erstellen, Kompilieren, Linken, Anhängen und Aktivieren von Shader- und Programmobjekten nötig sind. &lt;br /&gt;
* [[GL_ARB_Vertex_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Vertexebene hinzu. &lt;br /&gt;
* [[GL_ARB_Fragment_Shader]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_shader.txt Orginal Spezifikation])&lt;br /&gt;
: Fügt der OpenGL Programmierbarkeit auf Fragmentebene hinzu. &lt;br /&gt;
* [[GL_ARB_Shading_Language_100]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/shading_language_100.txt Orginal Spezifikation])&lt;br /&gt;
: Gibt die unterstützte Version von glSlang an, momentan 1.00.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objekte==&lt;br /&gt;
Im Zuge der Vereinheitlichung der GL wird immer häufiger in Objekte gekapselt, deren API dann auch aneinander angelehnt ist. Ziel ist, dabei die Programmierung der GL uniform zu machen, so dass z.B. zwischen dem Erstellen und Verwalten eines Vertex-Buffer-Objektes oder eines Shader-Objektes kaum ein Unterschied besteht (demnächst kommen dann auch Pixel-Buffer-Objekte dazu). Mit glSlang wurden dann im Zuge dieser Aktion zwei neue Objekte eingeführt, deren Definition ihr euch unbedingt einprägen solltet :&lt;br /&gt;
&lt;br /&gt;
* '''Programmobjekt'''&lt;br /&gt;
:Ein Objekt, an das die Shader später angebunden werden. Bietet Funktionalität zum Linken der Shader und prüft dabei die Kompatibilität zwischen Vertex- und Fragmentshader.&lt;br /&gt;
&lt;br /&gt;
* '''Shaderobjekt'''&lt;br /&gt;
:Dieses Objekt verwaltet den Quellcodestring eines Shaders und ist entweder vom Typ '''GL_VERTEX_SHADER_ARB''' oder '''GL_FRAGMENT_SHADER_ARB'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Resourcen==&lt;br /&gt;
Die Shadersprache ist keinesfalls final und es wurden bereits diverse Ausdrücke für zukünftige Verwendung reserviert, denn ein Ziel bei ihrer Entwicklung war es, sie so zukunftsorientiert zu gestalten, dass auch Grafikkarten der nächsten und übernächsten Generation voll ausgenutzt werden können. Damit einher geht die Tatsache, dass sich die Spezifikationen in Zukunft ändern/erweitern werden, weshalb man da immer einen Blick hineinwerfen sollte. Die Anlaufstelle dafür ist natürlich die [http://www.3dlabs.com/support/developer/ogl2/index.htm GL2-Seite von 3D-Labs], wo u.a. auch ein OGL2-SDK und diverse Whitepapers als PDFs angeboten werden, in denen auch stattgefundene Änderungen an glSlang dokumentiert sind.&lt;br /&gt;
&lt;br /&gt;
=GLSL im Programm=&lt;br /&gt;
Bevor wir uns mit der Syntax von glSlang beschäftigen, zeige ich euch erstmal, wie ihr Shader in euer Programm einbindet und nutzt. Warum das zuerst? Ganz einfach deshalb, weil ihr dann das, was ihr im glSlang-Syntaxteil lernt, direkt in eurer Testanwendung verwenden könnt. Hoffe diese Entscheidung klingt logisch und findet Anklang.&lt;br /&gt;
&lt;br /&gt;
Zuerst benötigen wir natürlich unsere Objekte. Zum einen ein ''Programmobjekt'', an das unsere Shader gebunden werden, und zwei ''Shaderobjekte'', die den Quellcode unseres Vertex bzw. Fragment Shaders aufnehmen. Dazu wurde eigens der neue &amp;quot;Datentyp&amp;quot; {{INLINE_CODE|glHandle}} eingeführt, der ein Objekthandle repräsentiert. Wir deklarieren also wie folgt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        : GLhandle;&lt;br /&gt;
 VertexShaderObject   : GLhandle;&lt;br /&gt;
 FragmentShaderObject : GLhandle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nach dieser Deklaration können wir dann damit beginnen unsere Objekte zu erstellen. Den Anfang macht das Programmobjekt :&lt;br /&gt;
&lt;br /&gt;
 ProgramObject        := glCreateProgram;&lt;br /&gt;
&lt;br /&gt;
Die Funktion [[glCreateProgram]] erstellt uns oben ein leeres Programmobjekt und gibt ein gültiges Handle darauf zurück.&lt;br /&gt;
&lt;br /&gt;
Weiter gehts mit der Erstellung unseres Vertex bzw. Fragment Shaders :&lt;br /&gt;
&lt;br /&gt;
 VertexShaderObject   := glCreateShader(GL_VERTEX_SHADER);&lt;br /&gt;
 FragmentShaderObject := glCreateShader(GL_FRAGMENT_SHADER);&lt;br /&gt;
&lt;br /&gt;
[[glCreateShader]] dient zur Generierung eines leeren Shaderobjektes. Momentan unterstützt diese Funktion VertexShader und FragmentShader.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun also zwei gültige Shaderobjekte haben, wollen wir diese auch mit entsprechendem Quellcode versorgen :&lt;br /&gt;
&lt;br /&gt;
 glShaderSource(VertexShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
 glShaderSource(FragmentShaderObject, 1, @ShaderText, @ShaderLength);&lt;br /&gt;
&lt;br /&gt;
Via [[glShaderSource]] setzen wir den Quellcode eines Shaderobjektes ''komplett'' neu. Zum Laden des Quellcodes bietet sich unter Delphi übrigens eine TStringList geradezu an. Es sollte beachtet werden, dass der Quellcode zu diesem Zeitpunkt ''nicht geparst'' wird, also keine Fehleruntersuchung stattfindet.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode wurde jetzt also an unsere Shaderobjekte gebunden und sollte dann natürlich auch noch kompiliert werden :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 glCompileShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Der glSlang-Compiler des Treibers wird bei einem Aufruf von [[glCompileShader]] versuchen, unsere Shader zu kompilieren. Sofern diese keine Fehler aufweisen, sollte dies auch erfolgreich sein. Wenn nicht, dann spuckt uns der Shadercompiler (je nach Treiber) recht detaillierte Infos aus. Wie man an diese Infos kommt könnt ihr gleich nachlesen.&lt;br /&gt;
&lt;br /&gt;
Wenn unsere Shader dann kompiliert werden konnten, ist es Zeit, diese an unser anfangs erstelltes Programmobjekt anzuhängen :&lt;br /&gt;
&lt;br /&gt;
 glAttachShader(ProgramObject, VertexShaderObject);&lt;br /&gt;
 glAttachShader(ProgramObject, FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
Nachdem die Shaderobjekte nun an das Programmobjekt angehängt wurden, werden diese nicht mehr benötigt und ihre Resourcen können freigegeben werden :&lt;br /&gt;
&lt;br /&gt;
 glDeleteShader(VertexShaderObject);&lt;br /&gt;
 glDeleteShader(FragmentShaderObject);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Am Schluß müssen wir dann noch unsere ans Programmobjekt gebundenen Shader linken :&lt;br /&gt;
&lt;br /&gt;
 glLinkProgram(ProgramObject);&lt;br /&gt;
&lt;br /&gt;
Während [[glCompileShader]] unsere Shader auf syntaktische Fehler innerhalb ihres lokalen Raums geprüft hat, werden beim Linken durch [[glLinkProgram]] die angehangenen Shader zu einem ausführbaren Shader gelinkt. Folgende Bedingungen führen zu einem '''Linkerfehler''':&lt;br /&gt;
&lt;br /&gt;
* Die Zahl der von der Implementation unterstützten Attributvariablen wurde überschritten&lt;br /&gt;
* Der Speicherplatz für Uniformvariablen wurde überschritten&lt;br /&gt;
* Die Zahl der von der Implementation angebotenen Sampler wurde überschritten&lt;br /&gt;
* Die main-Funktion fehlt&lt;br /&gt;
* Die Liste der Varying-Variablen des Vertexshaders stimmt nicht mit der des Fragmentshaders überein&lt;br /&gt;
* Funktions- oder Variablenname nicht gefunden&lt;br /&gt;
* Eine gemeinsame Globale ist mit unterschiedlichen Werten oder Typen initialisiert worden&lt;br /&gt;
* Zwei Sampler unterschiedlichen Typs zeigen auf die selbe Textureneinheit&lt;br /&gt;
* Ein oder mehrere angehangene(r) Shader wurden nicht erfolgreich kompiliert&lt;br /&gt;
&lt;br /&gt;
Die Nutzung von glSlang im eigenen Programm ist wie oben erkennbar also nicht wirklich schwer und innerhalb kurzer Zeit realisiert. Natürlich ist es auch möglich z.B. nur einen VertexShader oder nur einen FragmentShader an ein Programmobjekt zu binden.&lt;br /&gt;
&lt;br /&gt;
Noch eine kleine Notiz zum Löschen der Shader mittel [[glDeleteShader]] : Da Shader(objekte) einen Referenzzähler besitzen und erst gelöscht werden wenn diese nirgendwo mehr benötigt werden, ist es nicht falsch diese vor dem Linkvorgang zu löschen. Allerdings spielt es letztendlich keine Rolle ob die Löschanweisung vorher der nachher ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fehlererkennung==&lt;br /&gt;
Natürlich wird es ohne Fehlerausgabe recht schwer, etwaige Probleme in einem Vertex- oder Fragmentshader zu finden. Doch auch in diesem Bereich wurde glSlang recht gut durchdacht und es wurden zwei Funktionen eingeführt, welche im Zusammenspiel die Fehlersuche recht einfach machen, nämlich [[glGetShaderInfoLog]] und [[glGetShader]] mit dem Argument {{INLINE_CODE|GL_OBJECT_INFO_LOG_LENGTH}}. Erstere Funktion liefert uns einen Logstring, während uns letztere Funktion dessen Länge angibt. Der Logstring wird verändert, sobald ein Shader kompiliert oder ein Programm gelinkt wird.&lt;br /&gt;
&lt;br /&gt;
Um die Ausgabe dieses Logs so einfach wie möglich zu machen, bietet es sich an beide in einer einfach Funktion unterzubringen :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;function glSlang_GetInfoLog(pShader : GLHandleARB) : String;&lt;br /&gt;
var&lt;br /&gt;
 blen,slen : GLInt;&lt;br /&gt;
 InfoLog   : PGLCharARB;&lt;br /&gt;
begin&lt;br /&gt;
glGetShaderiv(glObject, GL_INFO_LOG_LENGTH , @blen);&lt;br /&gt;
if blen &amp;gt; 1 then&lt;br /&gt;
 begin&lt;br /&gt;
 GetMem(InfoLog, blen*SizeOf(GLCharARB));&lt;br /&gt;
 glGetShaderInfoLog(pShader, blen, slen, InfoLog);&lt;br /&gt;
 Result := PChar(InfoLog);&lt;br /&gt;
 Dispose(InfoLog);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion ist recht leicht erklärt : Zuerst lassen wir uns über {{INLINE_CODE|glGetShaderiv}} mitteilen wie lang der aktuelle Infolog ist. Sollte dort tatsächlich etwas drinstehen (blen &amp;gt; 1), dann lassen wir uns dessen Inhalt via {{INLINE_CODE|glGetShaderInfoLog}} in {{INLINE_CODE|InfoLog}} ausgeben und liefern diesen als Ergebnis zurück.&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt wird nur nach dem Kompilieren eines Shaders bzw. dem Linken eines Programmobjektes ein Infolog erstellt. Es bietet sich dadurch an, direkt danach einen solchen Aufruf zu machen :&lt;br /&gt;
&lt;br /&gt;
 glCompileShader(VertexShaderObject);&lt;br /&gt;
 ShowMessage(glSlang_GetInfoLog(VertexShaderObject));&lt;br /&gt;
&lt;br /&gt;
Wenn unser Vertex Shader komplett fehlerfrei kompiliert werden konnte, dann sehen wir als Ergebnis nur einen leeren Dialog. Ist dies nicht der Fall, so werden wir vom Treiber mit recht detaillierten Fehlerinformationen &amp;quot;belohnt&amp;quot;, z.B. so :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL_error_vshader.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auch das Infolog nach dem Linken des Programmobjektes dürfte, selbst wenn keine Fehler vorkommen, recht interessant sein, das sieht dann nämlich so aus :&lt;br /&gt;
&lt;br /&gt;
[[Bild:GLSL info programobject.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen, wird uns nach dem erfolgreichen Linken auch gesagt, ob und welcher Shader in Hardware bzw. Software läuft. Für Debuggingzwecke sicherlich eine mehr als brauchbare Information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Shader benutzen==&lt;br /&gt;
Um den Shader auch für die nächsten Polygone zu benutzen oder Uniformparameter übergeben zu können, ruft man die Funktion&lt;br /&gt;
 glUseProgramt(ProgramObject);&lt;br /&gt;
um alle Shader zu deaktivieren, ruft man dieselbe Funktion mit dem Parameter 0.&lt;br /&gt;
&lt;br /&gt;
==Parameterübergabe==&lt;br /&gt;
Uniformparameter (mehr dazu später) stellen die Schnittstelle zwischen eurem Programm und dem Shader dar, werden also genutzt um Daten aus dem Programm heraus an einen Shader zu übergeben. Zur Übergabe dieser Parameter bietet OpenGL diverse Funktionen, die alle Abkömmlinge von [[glUniform]] sind. Während mit {{INLINE_CODE|glUniform4f}} z.B. ein Vier-Komponentenvektor an das Programmobjekt übergeben wird, kann man mittels {{INLINE_CODE|glUniformMatrix4fv}} ganze Matrizen schnell und einfach übergeben. Ausserdem gibt es nun die Möglichkeit Uniformparameter direkt über ihren Namen, statt wie unter ARB_FP/VP über einen festen Index zu adressieren. Die Funktion [[glGetUniformLocationARB]] gibt anhand des übergebenen Parameternamens dessen Position zurück. Man kann also ganz einfach über den Namen drauf zugreifen :&lt;br /&gt;
&lt;br /&gt;
 glUniform3f(glGetUniformLocation(ProgramObject, PGLCharARB('LightPosition')), LPos[0], LPos[1], LPos[2]);&lt;br /&gt;
 glUniform1i(glGetUniformLocation(ProgramObject, PGLCharARB('texSamplerTMU3')), 3);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wichtig ist hier, das man je nach Parametertyp auch die passende Anzahl von Argumenten übergibt. Also für einen 4-Komponenten Floatvektor {{INLINE_CODE|glUniform4fARB}} und für einen einfachen Integerwert (z.B. Textureinheit für einen Sampler) glUnifrom1iARB. Auch nicht vergessen dürft ihr, das die Namen der Parameter genauso wie im Shader geschrieben werden müssen, also Groß- und Kleinschreibung beachtet werden muß.&lt;br /&gt;
&lt;br /&gt;
=Die Shadersprache=&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns mit der Einbindung der glSlang-Shader in unser Programm beschäftigt haben, wollen wir uns in den folgenden Kapiteln um die Sprachelemente von glSlang kümmern. Wie schon gesagt basiert glSlang auf ANSI-C, wurde allerdings um speziell auf den Zielbereich angepasste Vektor- und Matrixtypen und einige C++-Features wie das freie deklarieren von Variablen an jeder Stelle und das Funktionsüberladen auf Basis des Argumenttyps erweitert. Wer sich ein wenig mit C/C++ auskennt sollte also in der nun folgenden Materie keine Probleme bekommen.&lt;br /&gt;
&lt;br /&gt;
'''Obligatorische Hinweise für verwöhnte Delphi-Nutzer : '''&lt;br /&gt;
*Wie von C/C++ her gewohnt, spielt auch in glSlang die Groß- und Kleinschreibung eine wichtige Rolle, also bitte achtet darauf. gl_Position ist eine komplett andere Variable als z.B. gl_position.&lt;br /&gt;
*Es findet keine automatische Typenkonvertierung statt. Das bedeutet also das float MyFloat = 1 ungültig ist und es in dem Falle float MyFloat = 1.0 heissen muss. Typecasts müssen also immer manuell stattfinden, z.B. MyFloat = float(MyInt).&lt;br /&gt;
&lt;br /&gt;
'''Kleine Programmstrukturkunde für C-Unkundige :'''&amp;lt;br&amp;gt;&lt;br /&gt;
Da sicherlich einige Delpher nie richtig was mit C gemacht haben, zeige ich mal anhand eines kleinen Beispieles (das auf keinen Fall nen brauchbaren Shader darstellt) den grundlegenden Aufbau eines glSlang-Shaders, der natürlich dem Aufbau eines C-Programmes stark ähnelt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 VariableA;&lt;br /&gt;
float VariableB;&lt;br /&gt;
vec3  VariableC;&lt;br /&gt;
const float KonstanteA = 256.0;&lt;br /&gt;
&lt;br /&gt;
float MyFunction(vec4 ArgumentA)&lt;br /&gt;
 {&lt;br /&gt;
 float FunktionsVariableA = float(5.0);&lt;br /&gt;
&lt;br /&gt;
 return float(ArgumentA * (FunktionsVariableA + KonstanteA));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
// Ich bin ein Kommentar&lt;br /&gt;
/* Und ich auch */&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht doch recht bekannt aus, unser Programmaufbau. Delphi und C haben ja so einige Grundlagen gleich, darunter auch der ungefähre Programmaufbau. Ausserhalb jeglicher Funktionen legen wir am Programmanfang unsere Variablen, Konstanten und Attribute fest, die dann ''global'' nutzbar sind, also in jeder Funktion.&lt;br /&gt;
&lt;br /&gt;
Darunter deklarieren wir dann eine kleine Funktion. Wie auch bei den Variablendeklarationen wird hier der Rückgabetyp nicht wie bei Pascal nach dem Funktionsnamen untergebracht, sondern davor. Innerhalb der Funktion können dann wieder Variablen deklariert werden, die dann allerdings ''lokal'', also nur in dieser Funktion nutzbar sind. Vorteil dieser Deklaration ist die Tatsache, dass je nach Grafikkarte nur bestimmt viele globale Variablen deklariert werden können. Wenn möglich sollte man also mit lokalen Vorlieb nehmen. Unsere Funktion gibt dann natürlich noch via return einen Wert zurück, ''was gemacht werden muss'', sofern man diese nicht als void deklariert hat (entspräche dann einer Prozedur in Pascal). Wird dies nicht getan, so spuckt der Compiler einen Fehler aus.&lt;br /&gt;
&lt;br /&gt;
Auch wichtig sind natürlich Kommentare. Erste Variante (Doppelslash) ist auch in der Pascalwelt verfügbar und kommentiert eine einzelne Zeile aus. Die Variante darunter kann man für Kommentarblöcke nutzen (/* .. */) und entspricht den Kommentaren in geschweiften Klammern in Delphi.&lt;br /&gt;
&lt;br /&gt;
Danach kommt dann die '''wichtigste Funktion''' des Shaders, nämlich '''main''', die in keinem Shader fehlen darf. Sie stellt quasi den Programmkörper dar und ist oft auch die einzige Funktion in einem Shader. Sie erhält weder ein Argument, noch gibt sie einen Wert zurück.&lt;br /&gt;
&lt;br /&gt;
Soviel also zum grundlegenden Aufbau eines Shader. Hoffe das jetzt alle die in C nicht so bewandert sind damit klar kommen, und dann bald ihre ersten glSlang-Shader schreiben können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Datentypen==&lt;br /&gt;
&lt;br /&gt;
Obwohl einige Datentypen aus C übernommen wurden, sieht man der Typenliste an, das diese speziell auf den 3D-Bereich zugeschnitten wurde. Variablen müssen vor ihrer Nutzung eindeutig deklariert sein, Typecasting erfolgt über Konstruktoren (dazu später mehr). Folgende Datentypen stehen sowohl im Vertex- als auch Fragmentshader zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Datentyp  	&lt;br /&gt;
!Erklärung&lt;br /&gt;
|-&lt;br /&gt;
|void 	&lt;br /&gt;
|Für Funktionen die keinen Wert zurückgeben&lt;br /&gt;
|-&lt;br /&gt;
|bool 	&lt;br /&gt;
|Konditionaler Typ, entweder true (wahr) oder false (falsch)&lt;br /&gt;
|-&lt;br /&gt;
|int 	&lt;br /&gt;
|Vorzeichenbehafteter Integerwert&lt;br /&gt;
|-&lt;br /&gt;
|float 	&lt;br /&gt;
|Fließkommaskalar mit Singlegenauigkeit (32 Bit)&lt;br /&gt;
|-&lt;br /&gt;
|vec2 	&lt;br /&gt;
|2-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec3 	&lt;br /&gt;
|3-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|vec4 	&lt;br /&gt;
|4-Komponenten Fließkommavektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec2 	&lt;br /&gt;
|2-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec3 	&lt;br /&gt;
|3-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|bvec4 	&lt;br /&gt;
|4-Komponenten Booleanvektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec2 	&lt;br /&gt;
|2-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec3 	&lt;br /&gt;
|3-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|ivec4 	&lt;br /&gt;
|4-Komponenten Integervektor&lt;br /&gt;
|-&lt;br /&gt;
|mat2 	&lt;br /&gt;
|2x2 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat3 	&lt;br /&gt;
|3x3 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|mat4 	&lt;br /&gt;
|4x4 Fließkommamatrix&lt;br /&gt;
|-&lt;br /&gt;
|sampler1D 	&lt;br /&gt;
|Zugriff auf 1D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler2D 	&lt;br /&gt;
|Zugriff auf 2D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|sampler3D 	&lt;br /&gt;
|Zugriff auf 3D-Textur&lt;br /&gt;
|-&lt;br /&gt;
|samplerCube 	&lt;br /&gt;
|Zugriff auf Cubemap&lt;br /&gt;
|-&lt;br /&gt;
|sampler1DShadow 	&lt;br /&gt;
|Zugriff auf 1D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|sampler2DShadow 	&lt;br /&gt;
|Zugriff auf 2D-Tiefentextur mit Vergleichsoperation&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Die sampler-Typen stellen eine besondere Klasse dar und werden im Kapitel 6.7 genauer erklärt, inklusive einiger Anwendungsbeispiele.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Arrays===&lt;br /&gt;
&lt;br /&gt;
Natürlich unterstützt glSlang auch Arrays, die wie in C deklariert werden und deren Index bei 0 beginnt. Folgendes Array im Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float temp[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
beginnt also bei Index 0 und endet bei Index 2. Im Gegensatz zu C lassen sich Arrays in glSlang allerdings ''nicht bei der Initialisierung vorbelegen''. Wenn ein Array als Parameter einer Funktion deklariert wird, so darf dieses keine Dimensionierung erhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Strukturen===&lt;br /&gt;
&lt;br /&gt;
Neu ggü. ARB_FP/VP ist nun auch die Möglichkeit, Strukturen in einem Shader zu deklarieren. Vor allem die Übersicht komplexerer Shader kann dadurch stark verbessert werden. Strukturen werden wie gewohnt mit dem Schlüsselwort {{INLINE_CODE|struct}} eingeleitet und können dann zur Typisierung von Variablen genutzt werden. Folgendes Beispiel dürfte die Nutzung verdeutlichen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct light&lt;br /&gt;
 {&lt;br /&gt;
 bool active;&lt;br /&gt;
 float intensity;&lt;br /&gt;
 vec3 position;&lt;br /&gt;
 vec3 color;&lt;br /&gt;
 };&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Im Shader können dann neue Variablen von diesem Typ ganz einfach deklariert werden :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
 light LightSource[3];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Zugriff auf die Elemente der Struktur erfolgt dann wie gewohnt über den Punkt :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
LightSource[3].position = vec3(1.0, 1.0, 5.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Typenqualifzierer==&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Typendeklaration kann eine Variable noch einen Typenqualifizerer vorangestellt bekommen, der an den Anfang der Deklaration gehört.&lt;br /&gt;
&lt;br /&gt;
* '''const'''&lt;br /&gt;
: Festgelegte (nur lesen) Konstante bzw. nur lesbarer Funktionsparameter.&lt;br /&gt;
&lt;br /&gt;
* '''uniform'''&lt;br /&gt;
: Ein den ganzen Shader über gleichbleibender Wert, der eine Schnittstelle zwischen dem Shader und der OpenGL-Anwendung darstellt. Ein Uniformwert wird in der Hauptanwendung an den entsprechenden Shader übergeben und kann dort dann genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* '''attribute'''&lt;br /&gt;
: Nur lesbare Werte die eine Verbindung zwischen dem Shader und der OpenGL-VertexAPI darstellen (z.B. VertexParameter eines VertexArrays). Natürlich nur in einem Vertex Shader nutzbar.&lt;br /&gt;
&lt;br /&gt;
* '''varying'''&lt;br /&gt;
: Stellt die Verbindung zwischen einem Vertex- und einem FragmentShader dar. Werden im VertexShader geschrieben und dann perspektivisch korrekt über die Primitive interpoliert, um dann im Fragment Shader gelesen werden zu können. Nutzbar sind hier nur die Typen float, vec2, vec3, vec4, mat2, mat3 und mat4, Strukturen und andere Datentypen können nicht varying sein. Die Namen einer varying-Variable müssen sowohl im VertexShader als auch im FragmentShader gleich sein.&lt;br /&gt;
&lt;br /&gt;
* '''in'''&lt;br /&gt;
: Für Variablen die an eine Funktion übergeben und dort ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* '''out'''&lt;br /&gt;
: Für Variablen die von einer Funktion nach aussen zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
* '''inout'''&lt;br /&gt;
: Für Variablen die sowohl an eine Funktion übergeben als auch von dieser zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um obige Auflistung nicht leer im Raum stehen zu lassen zeige ich ein paar Beispiele die hoffentlich zum Verständnis beitragen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Vertexnormale soll an einen FragmenShader (interpoliert) übergeben werden :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
VertexNormal = normalize(MV_IT * gl_Normal);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im FragmentShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 VertexNormal;&lt;br /&gt;
...&lt;br /&gt;
TempVector = VertexNormal*...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Uniformparameter zur nachträglichen Farbänderung der Szene wird im Programm übergeben :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = GlobalColor * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
:Im Programm :&lt;br /&gt;
&lt;br /&gt;
 glUniform4fARB(glSlang_GetUniLoc(ProgramObject, 'GlobalColor'), Col[0], Col[1], Col[2], Col[3]);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Beispiel C=== &lt;br /&gt;
Konstante zur festen Farbänderung :&lt;br /&gt;
&lt;br /&gt;
:Im VertexShader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
const vec4 ColorBias = vec4(0.2, 0.3, 0.0, 0.0);&lt;br /&gt;
...&lt;br /&gt;
gl_FrontColor = ColorBias * gl_Color;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==Konstruktoren==&lt;br /&gt;
&lt;br /&gt;
Um in einem Shader ''Vektoren'' oder ''Matrizen'' mit Werten zu belegen, gibt es sogenannte Konstruktoren (nicht zu verwechseln mit z.B. Klassenkonstruktoren unter Delphi), die im Endeffekt nichts anderes als Funktionen zur Vorbelegung von Vektoren oder Matrizen darstellen. Dabei trägt der Konstruktor den selben Namen wie die Typendeklaration, also lässt sich eine Variable vom Typ {{INLINE_CODE|vec4}} mit dem Konstruktor {{INLINE_CODE|vec4(float, float, float, float)}} initialisieren.&lt;br /&gt;
&lt;br /&gt;
Allerdings hat man sich recht viel Mühe bei dieser Konstruktorgeschichte gemacht, so dass man einen vec4 nicht unbedingt mit einem {{INLINE_CODE|vec4}}-Konstruktor vorbelegen muss, sondern es vielseitige Möglichkeiten gibt. Um dies zu verdeutlichen gibts ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(1.0, 0.0, 0.0, 0.0);&lt;br /&gt;
vec4 Color = vec4(MyVec3, 1.0);&lt;br /&gt;
vec4 Color = vec4(MyVec2_A, MyVec2_B);&lt;br /&gt;
&lt;br /&gt;
vec3 LVec  = vec3(MyVec4);&lt;br /&gt;
vec2 Tmp   = vec2(MyVec3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trotz der recht wenigen Beispiele sollte schnell erkennbar sein, das man hier wirklich sehr viele Kombinationsmöglichkeiten hat, die dann gültig sind ''wenn man mindestens auf die benötigte Anzahl der Argumente kommt''. Im vorletzten Beispiel wird z.B. ein 3-Komponentenvektor aus einem 4-Komponentenvektor initialisiert. Das erzeugt keinen Fehler, sondern führt dazu das {{INLINE_CODE|vec3.x, vec3.y, vec3.z}} aus MyVec4 übernommen werden und MyVec4.w einfach ignoriert wird.&lt;br /&gt;
&lt;br /&gt;
Das Umkehrbeispiel, also&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec4 Color = vec4(MyVec3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
funktioniert allerdings nicht, da hier die Zahl der benötigten Argumente nicht erreicht wird. In diesem Falle müsste es dann&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt; &lt;br /&gt;
vec4 Color = vec4(MyVec3, 0.0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
heissen.&lt;br /&gt;
&lt;br /&gt;
Obiges gilt natürlich auch für ''Matrixkonstruktoren'', hier sind z.B. folgende Konstuktoren denkbar, obwohl eigentlich alle Möglichkeiten nutzbar sind, ''solange die benötigte Zahl an Argumenten erreicht wird'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
mat4 MyMatrix = mat4(MyVec4, MyVec4, MyVec4, MyVec4);&lt;br /&gt;
mat2 MyMatrix = mat4(1.0, 0.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 1.0, 0.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 1.0, 0.0,&lt;br /&gt;
                     0.0, 0.0, 0.0, 1.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixkomponenten==&lt;br /&gt;
&lt;br /&gt;
Was natürlich in keiner Shadersprache fehlen darf, ist der leichte Zugriff auf die einzelnen Komponenten eines Vektors. glSlang bietet, je nach Anwendungsgebiet gleich drei Namensets für den Zugriff auf die Komponenten eines solchen Vektors, welches Set man nutzen will bleibt natürlich frei und ist unabhängig von der Deklaration eines Vektors. Man sollte nur darauf achten, beim gleichzeitigen Zugriff auf mehrere Komponenten im gleichen Namenset zu verbleiben :&lt;br /&gt;
&lt;br /&gt;
* {x, y, z, w}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Punkte, Normale oder sonstige Vertexdaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {r, g, b, a}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Farbwerte repräsentieren.&lt;br /&gt;
&lt;br /&gt;
* {s, t, p, q}&lt;br /&gt;
:Für den Zugriff auf Vektoren die Texturkoordinaten repräsentieren.&lt;br /&gt;
&lt;br /&gt;
Ein paar Beispiele zur Unterstreichung des oben gesagten :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
v4.rgba = vec4(1.0, 0.0, 0.0, 0.0);  // gültig&lt;br /&gt;
v4.rgzw = vec4(1.0, 1.0, 1.0, 2.0);  // Ungültig, da verschiedenen Namensets&lt;br /&gt;
v2.rgb  = vec3(1.0, 2.0, 1.0);       // Ungültig, da vec2 nur r+g besitzt&lt;br /&gt;
v2.xx   = vec2(5.0, 3.0);            // Ungültig, da 2 mal gleiche Komponente&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch der Zugriff auf die Komponenten einer Matrix geht leicht von der Hand. Namensets wie bei den Vektoren gibt es hier natürlich keine, aber folgende Beispiele sollen den Zugriff aufzeigen :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
MyMat4[2]    = vec4(1.0); // Setzt die 3.Zeile der Matrix komplett auf 1.0&lt;br /&gt;
MyMat4[3][3] = 3.5;       // Setzt das Element unren rechts auf 3.5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Matrixelemente ausserhalb ihrer Dimension (also z.B. MyMat4[4][4]) liefert unvorhersehabre Ergebnise, also sollte man auf diese Fälle prüfen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektor- und Matrixoperationen==&lt;br /&gt;
&lt;br /&gt;
Wie von C gewohnt sind in glSlang so ziemlich alle Operatoren die man auf Matrizen oder Vektoren anwenden kann überladen, so das man nicht umständlich über selbstgeschriebene Funktionen kombinieren muss. Darüber hinaus ist es in den meisten Fällen auch möglich ohne Konvertierung Fließkommawerte mit kompletten Matrizen oder Vektoren zu kombinieren. Folgende Beispiele zeigen einige der vielfältigen Kombinationsmöglichkeiten auf :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
float factor;&lt;br /&gt;
&lt;br /&gt;
vec3 dest = source + factor; &lt;br /&gt;
&lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = source.x + factor;&lt;br /&gt;
dest.y = source.y + factor;&lt;br /&gt;
dest.z = source.z + factor;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Matrix * Vektor ist auch ohne manuelle Konvertierung möglich :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
vec3  dest;&lt;br /&gt;
vec3  source;&lt;br /&gt;
mat3  MyMat;&lt;br /&gt;
 &lt;br /&gt;
dest = source * MyMat; &lt;br /&gt;
 &lt;br /&gt;
// Ist gleich&lt;br /&gt;
dest.x = dot(source, MyMat[0]);&lt;br /&gt;
dest.y = dot(source, MyMat[1]);&lt;br /&gt;
dest.z = dot(source, MyMat[2]);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier sind die Möglichkeiten fast unbeschränkt und zeigen wieder wie flexibel glSlang ausgelegt ist. &lt;br /&gt;
&lt;br /&gt;
==Operatoren==&lt;br /&gt;
&lt;br /&gt;
glSlang bietet (momentan) folgende Operatoren, die Liste ist nach ihrer Gewichtung sortiert (Anfang = höchste). Alle ''reservierten'' Operatoren werden erst in kommender Hardware/glSlang-Versionen nutzbar sein :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div  align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!Operatorklasse  	&lt;br /&gt;
!Operatoren  	&lt;br /&gt;
!Assoziation&lt;br /&gt;
|-&lt;br /&gt;
|Gruppering 	&lt;br /&gt;
|() 	&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|Arrayindizierung&amp;lt;br&amp;gt;Funktionsaufrufe und Konstruktoren&amp;lt;br&amp;gt;Strukturfeldwahl und Swizzle&amp;lt;br&amp;gt;Postinkrement und -dekrement&amp;lt;br&amp;gt; 	&lt;br /&gt;
|[]&amp;lt;br&amp;gt;()&amp;lt;br&amp;gt;.&amp;lt;br&amp;gt;++ -- 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Prefixinkrement- und dekrement&amp;lt;br&amp;gt;Einheitlich (~ reserviert) 	&lt;br /&gt;
| ++ --&amp;lt;br&amp;gt; + - ~ ! 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Mulitplikation (% reserviert) 	&lt;br /&gt;
|* / % 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Additiv 	&lt;br /&gt;
| + - 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises Verschieben (reserviert) 	&lt;br /&gt;
|&amp;lt;&amp;lt;  &amp;gt;&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Relation 	&lt;br /&gt;
|&amp;lt;  &amp;gt;  &amp;lt;=  &amp;gt;= 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Vergleich 	&lt;br /&gt;
|==  != 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises AND (reserviert) 	&lt;br /&gt;
|&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises XOR (reserviert) 	&lt;br /&gt;
|^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Bitweises OR (reserviert) 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches AND 	&lt;br /&gt;
|&amp;amp;&amp;amp; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches XOR 	&lt;br /&gt;
|^^ 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Logisches OR 	&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|Auswahl 	&lt;br /&gt;
|?: 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Zuweisung&amp;lt;br&amp;gt;Arithmetrische Zuweisung&amp;lt;br&amp;gt;(Modulis, Shift und bitweise Op. reserviert) 	&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;=&amp;lt;/nowiki&amp;gt;&amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;+= -=  *=  /=  %=&amp;lt;/nowiki&amp;gt; &amp;lt;br&amp;gt; &amp;lt;nowiki&amp;gt;&amp;lt;&amp;lt;=  &amp;gt;&amp;gt;= &amp;amp;=  ^=  |=&amp;lt;/nowiki&amp;gt; 	&lt;br /&gt;
|Rechts n. Links&lt;br /&gt;
|-&lt;br /&gt;
|Aufzählung 	&lt;br /&gt;
|, 	&lt;br /&gt;
|Links n. Rechts&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Funktionen==&lt;br /&gt;
&lt;br /&gt;
Ein großer Vorteil von Hochsprachen ist u.A. die Möglichkeit oft genutzte Codeteile in Funktionen (bzw. auch Prozeduren unter Pascal) zu verpacken um so Flexibilität als auch Übersichtlichkeit zu steigern. Wer schonmal was in C geschrieben hat, der wird sich jetzt sicherlich kein Kopfzerbrechen machen müssen. Funktionen werden in glSlang genauso nach folgendem Prinzip deklariert :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
RückgabeTyp FunktionsName(Typ0 Argument0, Typ1, Argument1, ... , TypN, ArgumentN)&lt;br /&gt;
 {&lt;br /&gt;
 return RückgabeWert;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen die ''nichts zurückgeben'' müssen mit dem RückgabeTyp {{INLINE_CODE|void}} deklariert werden, ausserdem entfällt dann logischerweise das {{INLINE_CODE|return}}. Falls die Funktion eines ihrere Argumente nach aussen übergeben soll, muss dieses Argument mit dem Typenqualifizierer out (Siehe Kapitel 4.2) versehen werden. ''Arrays'' können nur als Eingabeargumente übergeben werden und dürfen nich dimensioniert als Argument verwendet werden, sondern müssen mit leeren Klammern argumentiert werden.&lt;br /&gt;
Ein paar Beispiele :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void MeineFunktion(float EingabeWert; out float AusgabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 AusgabeWert = EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion gibt ''nichts'' zurück, aber gibt EingabeWert*MyConstValue im Ausgabeargument AusgabeWert nach aussen.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float MeineFunktion(float EingabeWert)&lt;br /&gt;
 {&lt;br /&gt;
 return EingabeWert*MyConstValue;&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bietet genau die selbe Funktionalität wie das Beispiel darüber. Allerdings wird hier der berechnete Wert als Ergebnis der Funktion zurückgeliefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
float VektorSumme(float v[])&lt;br /&gt;
 {&lt;br /&gt;
 return v[0]+v[1]+v[2]+v[3];&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie bereits gesagt darf ein Array als Argument keine Dimensionierung enthalten. Wenn man der Funktion also ein Array übergibt, sollte man vorher drauf achten das es entsprechend der in der Funktion genutzten Indizes dimensioniert wurde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==if-Anweisung==&lt;br /&gt;
&lt;br /&gt;
Selektion über eine if-Anweisung darf auch in keiner Hochsprache fehlen. Genauso wie in C oder Delphi erwartet auch hier die If-Anweisung einen boolschen Ausdruck (Wahr oder Falsch) und wird dann ausgeführt (wahr) bzw. verzweigt auf ein (wenn vorhanden) else (falsch). Verschachtelung ist wie erwartet auch möglich.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis : ''' &lt;br /&gt;
Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten im Fragmentshader kein Early-Out, was zur Folge hat das bei einer If-Anweisung immer alle Zweige ausgeführt werden. Am Ende wird dann aber nur ein Ergebnis geschrieben, die anderen verworfen. Auf solchen Karten bringen If-Anweisungen also im Normalfall keine Geschwindigkeitssteigerung, sondern oft eher das Gegenteil.&lt;br /&gt;
Neuere SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall, da hier dynamische Verzweigungen und auch Early-Out von der Hardware implementiert werden.&lt;br /&gt;
&lt;br /&gt;
==Schleifen==&lt;br /&gt;
&lt;br /&gt;
Auch Schleifen, ein wichtiges Konzept jeder Hochsprache haben ihren Weg in glSlang gefunden. Unterstützt werden folgende Schleifentypen :&lt;br /&gt;
&lt;br /&gt;
* '''for'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
for (Startausdruck; Durchlaufbedingung; Wiederholungsausdruck)&lt;br /&gt;
  {&lt;br /&gt;
   statement&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''while'''-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
while (Durchlaufbedingung)&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''do'''-while-Schleife&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
 {&lt;br /&gt;
  statement&lt;br /&gt;
 }&lt;br /&gt;
 while (Durchlaufbedingung)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Hinweis :''' Grafikkarten auf dem Stand des Shadermodells 2.0 (Radeon 9x00, Radeon X8x0, GeForceFX 5x00) unterstüzten Schleifen nicht in Hardware. Schleifen werden dann beim Kompilieren vom Treiber entrollt, wodurch natürlich Shader mit weitaus mehr Instruktionen als erwartet generiert werden. Von daher sollte man auf solchen Karten möglichst auf Schleifen verzichten, oder diese nur recht kurz halten. Bei SM3.0-Karten (Radeon X1x00, GeForce6x00 und höher) ist dass nicht mehr der Fall.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Variablen, Attribute und Konstanten=&lt;br /&gt;
Nachdem wir uns nun lange genug mit den minderinterssanten Elementen der glSlang-Syntax beschäftigt haben, gehts jetzt endlich an die wirklich interessanten Dinge. Wie schon ARB_VP/ARB_FP bringt auch glSlang jede Menge eingabauter Variablen, Attribute und Konstanten mit, deren Aliase sie recht leicht identifizierbar machen (ganz im Gegensatz zum Indexgewusel bei den DX-Shadern).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Vertex Shader==&lt;br /&gt;
Exklusiv im Vertex Shader stehen die folgenden Variablen zur Verfügung :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Position    muss geschrieben werden&lt;br /&gt;
:Dieser Variable '''muss''' im Vertexshader ein Wert zugewiesen werden, wird dies nicht getan ist das Ergebnis (sprich die Position des Vertex) undefiniert. Vorgesehen ist diese Variable für die ''homogene Position des Vertex'' und wird u.a. zum Clipping und Culling verwendet. Sie darf natürlich auch (mehrfach) geschrieben und ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
* float gl_PointSize    kann geschrieben werden&lt;br /&gt;
:Diese Variable wurde dazu vorgesehen um dort im VertexShader die Punktgröße in Pixeln hineinzuschreiben.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_ClipVertex    kann geschrieben werden&lt;br /&gt;
:Falls genutzt, sollten hier die Vertexkoordinaten die im Zusammenhang mit benutzerdefinierten Clippingplanes genutzt werden abgelegt werden. Wichtig ist, das gl_ClipVertex im selben Koordinatenraum wie die Clippingplane definiert ist.&lt;br /&gt;
&lt;br /&gt;
==Attribute im Vertex Shader==&lt;br /&gt;
&lt;br /&gt;
Folgende Attribute stehen nur im Vertex Shader zur Verfügung und '''können nur gelesen werden''' :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_Color&lt;br /&gt;
: Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_SecondaryColor&lt;br /&gt;
:Sekundärer Farbwert des Vertex.&lt;br /&gt;
* vec4 gl_Normal&lt;br /&gt;
:Normale des Vertex.&lt;br /&gt;
* vec4 gl_Vertex&lt;br /&gt;
:Koordinaten des Vertex;&lt;br /&gt;
* vec4 gl_MultiTexCoord0..7&lt;br /&gt;
:Texturkoordinaten auf Textureinheit 0..7.&lt;br /&gt;
* float gl_FogCoord&lt;br /&gt;
:Nebelkoordinate des Vertex. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Variablen im Fragment Shader==&lt;br /&gt;
&lt;br /&gt;
Im Fragment Shader sind folgende Variablen exklusiv nutzbar :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragColor&lt;br /&gt;
: Speichert den Farbwert des Fragmentes, der von folgenden Funktionen der festen Pipeline genutzt wird. Wird dieser Variable nichts zugewiesen, so ist ihr Inhalt undefiniert und darauf aufbauende Ergebnisse ebenfalls.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragData[0..15]&lt;br /&gt;
: Ersetzt gl_FragColor bei der Verwendung von multiplen Rendertargets. &lt;br /&gt;
&lt;br /&gt;
* float gl_FragDepth&lt;br /&gt;
: Durch schreiben dieser Variable kann man den von der festen Funktionspipeline ermittelten Tiefenwert überspringen, der mit {{INLINE_CODE|gl_FragCoord.z}} ausgelesen werden kann. Wird dieser Wert nicht geschrieben, nutzen folgende Funktionen der Pipeline den vorher fest berechneten Wert.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FragCoord    nur lesen&lt;br /&gt;
: In dieser Variable ist die Position des Fragmentes relativ zur Fensterposition im Format x,y,z,1/w abgelegt, wobei z den von der festen Funktionspipeline berechneten Tiefenwert enthält.&lt;br /&gt;
&lt;br /&gt;
* bool gl_FrontFacing    nur lesen&lt;br /&gt;
: Gibt an ob das Fragment zu einer nach vorne zeigenden Primitive gehört (=true). &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Bezug auf {{INLINE_CODE|gl_FragColor}} und {{INLINE_CODE|gl_FragDepth}} sei noch anzumerken das diese ''nicht'' in den Wertebereich 0..1 gebracht werden müssen, da dies später durch die feste Funktionspipeline automatisch gemacht wird.&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Varyings==&lt;br /&gt;
&lt;br /&gt;
Wie bereits in Kapitel 4.2 erwähnt, stellen Varyings eine Schnittstelle zwischen dem Vertex und dem Fragment Shader dar. Sie werden im Vertex Shader geschrieben und können dann im Fragment Shader ausgelesen werden, ohne das die folgenden Varyings dafür explizit deklariert werden müssen :&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontColor&lt;br /&gt;
: Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackColor&lt;br /&gt;
: Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_FrontSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Vorderseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_BackSecondaryColor&lt;br /&gt;
: Sekundäre Farbe der Rückseite des Vertex.&lt;br /&gt;
&lt;br /&gt;
* vec4 gl_TexCoord[x]&lt;br /&gt;
: Texturkoordinaten des Vertex auf Textureinheit x, wobei x die von der Hardware zur Verfügung gestellte Zahl der Textureinheiten-1 nicht überschreiten darf.&lt;br /&gt;
&lt;br /&gt;
* float gl_FogFragCoord&lt;br /&gt;
: Nebelkoordinate des Fragmentes. &lt;br /&gt;
&lt;br /&gt;
Die Varyings {{INLINE_CODE|gl_FrontColor, gl_FrontSecondaryColor, gl_BackColor}} und {{INLINE_CODE|gl_BackSecondaryColor}} können im FragmentShader nur unter den Aliases gl_Color bzw. gl_SecondaryColor gelesen werden. Welcher Wert des Vertex Shaders im Fragment Shader dort eingesetzt wird ist abhängig davon ob das Fragment zu einer nach vorne oder nach hinten zeigenden Primitive gehört.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Konstanten==&lt;br /&gt;
Auch diverse Konstanten wurden definiert um darauf schnell im Shader zugreifen zu können. In den Klammern stehen die von einer GL-Implementation als Mindestanforderung anzubietenden Werte. Alle Konstanten sind sowohl im Vertex als auch im Fragment Shader abrufbar :&lt;br /&gt;
&lt;br /&gt;
: OpenGL 1.0/1.2 :&lt;br /&gt;
* int gl_MaxLights (8)&lt;br /&gt;
* int gl_MaxClipPlanes (6)&lt;br /&gt;
* int gl_MaxTextureUnits (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: ARB_Fragment_Program :&lt;br /&gt;
* int gl_MaxTextureCoordsARB (2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Vertex_Shader :&lt;br /&gt;
* int gl_MaxVertexAttributesGL2 (16)&lt;br /&gt;
* int gl_MaxVertexUniformFloatsGL2 (512)&lt;br /&gt;
* int gl_MaxVaryingFloatsGL2 (32)&lt;br /&gt;
* int gl_MaxVertexTextureUnitsGL2 (1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: Fragment_Shader :&lt;br /&gt;
* int gl_MaxFragmentTextureUnitsGL2 (2)&lt;br /&gt;
* int gl_MaxFragmentUniformFloatsGL2 (64)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Eingebaute Uniformvariablen==&lt;br /&gt;
&lt;br /&gt;
Um den Zugriff auf OpenGL-Staten zu vereinfachen wurden in glSlang diverse Uniformvariablen zur direkten Verwendung im Shader eingebaut. Wie gewohnt wurden auch hier sinnvolle Namen verwendet, so dass eine tiefere Erklärung unnötig sein dürfte :&lt;br /&gt;
&lt;br /&gt;
* mat4 gl_ModelViewMatrix&lt;br /&gt;
* mat4 gl_ProjectionMatrix&lt;br /&gt;
* mat4 gl_ModelViewProjectionMatrix&lt;br /&gt;
* mat3 gl_NormalMatrix&lt;br /&gt;
:{{INLINE_CODE|gl_NormalMatrix}} repräsentiert die invertierten und anschließend transponierten oberen 3x3 Werte der {{INLINE_CODE|gl_ModelViewMatrix}}.&lt;br /&gt;
* mat4 gl_TextureMatrix[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
* float gl_NormalScale&lt;br /&gt;
: Gibt den unter OpenGL festgelegten Faktor zur Skalierung der Normalen zurück.&lt;br /&gt;
&lt;br /&gt;
* struct gl_DepthRangeParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_DepthRangeParameters&lt;br /&gt;
{&lt;br /&gt;
 float near;&lt;br /&gt;
 float far;&lt;br /&gt;
 float diff;&lt;br /&gt;
};&lt;br /&gt;
gl_DepthRangeParameters gl_DepthRange;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: Clippingplanes : &lt;br /&gt;
* vec4 gl_ClipPlane[gl_MaxClipPlanes]&lt;br /&gt;
  &lt;br /&gt;
*struct gl_PointParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_PointParameters&lt;br /&gt;
{&lt;br /&gt;
 float size;&lt;br /&gt;
 float sizeMin;&lt;br /&gt;
 float sizeMax;&lt;br /&gt;
 float fadeThresholdSize;&lt;br /&gt;
 float distanceConstantAttenuation;&lt;br /&gt;
 float distanceLinearAttenuation;&lt;br /&gt;
 float distanceQuadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_PointParameters gl_Point;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_MaterialParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_MaterialParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 emission;&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 float shininess;&lt;br /&gt;
};&lt;br /&gt;
gl_MaterialParameters gl_FrontMaterial;&lt;br /&gt;
gl_MaterialParameters gl_BackMaterial;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightSourceParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightSourceParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
 vec4 position;&lt;br /&gt;
 vec4 halfVector;&lt;br /&gt;
 vec3 spotDirection;&lt;br /&gt;
 float spotExponent;&lt;br /&gt;
 float spotCutoff;&lt;br /&gt;
 float spotCosCutoff;&lt;br /&gt;
 float constantAttenuation;&lt;br /&gt;
 float linearAttenuation;&lt;br /&gt;
 float quadraticAttenuation;&lt;br /&gt;
};&lt;br /&gt;
gl_LightSourceParameters gl_LightSource[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelParameters gl_LightModel;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightModelProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightModelProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 sceneColor;&lt;br /&gt;
};&lt;br /&gt;
gl_LightModelProducts gl_FrontLightModelProduct;&lt;br /&gt;
gl_LightModelProducts gl_BackLightModelProduct;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*struct gl_LightProducts&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_LightProducts&lt;br /&gt;
{&lt;br /&gt;
 vec4 ambient;&lt;br /&gt;
 vec4 diffuse;&lt;br /&gt;
 vec4 specular;&lt;br /&gt;
};&lt;br /&gt;
gl_LightProducts gl_FrontLightProduct[gl_MaxLights];&lt;br /&gt;
gl_LightProducts gl_BackLightProduct[gl_MaxLights];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* vec4 gl_TextureEnvColor[gl_MaxFragmentTextureUnitsGL2]&lt;br /&gt;
* vec4 gl_EyePlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_EyePlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneS[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneT[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneR[gl_MaxTextureCoordsARB]&lt;br /&gt;
* vec4 gl_ObjectPlaneQ[gl_MaxTextureCoordsARB]&lt;br /&gt;
&lt;br /&gt;
*struct gl_FogParameters&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
struct gl_FogParameters&lt;br /&gt;
{&lt;br /&gt;
 vec4 color;&lt;br /&gt;
 float density;&lt;br /&gt;
 float start;&lt;br /&gt;
 float end;&lt;br /&gt;
 float scale;&lt;br /&gt;
};&lt;br /&gt;
gl_FogParameters gl_Fog;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Diese recht umfangreiche GL-Stateliste sollte eigentlich jeden Bedarf decken und momentan gibts kaum einen OpenGL-Status den man so nicht in einem Shader abfragen bzw. nutzen kann.&lt;br /&gt;
&lt;br /&gt;
=Eingebaute Funktionen=&lt;br /&gt;
glSlang ist mit diversen Skalar- und Vektorfunktionen ausgestattet, die teilweise (idealerweise) sogar direkt in der Hardware ausgeführt werden, weshalb einer fertigen Funktion ggü. gleichwertigen eigenen Berechnungen immer der Vorzug zu geben ist.&lt;br /&gt;
{{Hinweis| ''genType'' kann vom Type float, vec2, vec3 oder vec4 sein, ''mat'' vom Typ mat2, mat3 oder mat4.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Trigonometrie und Winkel==&lt;br /&gt;
Alle übergebenen Winkel sollten, soweit nicht anders vermerkt, in Radien angegeben werden.&lt;br /&gt;
&lt;br /&gt;
* genType radians (genType degrees)&lt;br /&gt;
: Wandelt von Grad nach Radien. &lt;br /&gt;
* genType degrees (genType radians)&lt;br /&gt;
: Wandelt von Radien nach Grad.&lt;br /&gt;
* genType sin (genType angle)&lt;br /&gt;
: Gibt den Sinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType cos (genType angle)&lt;br /&gt;
: Gibt den Cosinus von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType tan (genType angle)&lt;br /&gt;
: Gibt den Tangens von Angle zurück, wobei Angle in Radien angegeben wird.&lt;br /&gt;
* genType asin (genType x)&lt;br /&gt;
: Liefert den Arcsinus von x zurück, also den Winkel dessen Sinus x ergeben würde.&lt;br /&gt;
* genType acos (genType x)&lt;br /&gt;
: Liefert den Arccosinus von x zurück, also den Winkel dessen Cosinus x ergeben würde.&lt;br /&gt;
* genType atan (genType y, genType x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x/y ergeben würde.&lt;br /&gt;
* genType atan (genType y_over_x)&lt;br /&gt;
: Liefert den Winkel zurück, dessen Tangens x über y ergeben würde.&lt;br /&gt;
&lt;br /&gt;
==Exponentiell==&lt;br /&gt;
* genType pow (genType x, genType y)&lt;br /&gt;
: Gibt x hoch y zurück.&lt;br /&gt;
* genType exp2 (genType x)&lt;br /&gt;
: Gibt 2 hoch x zurück.&lt;br /&gt;
* genType log2 (genType x)&lt;br /&gt;
: Gibt den Logarithmus zur Basis 2 von x zurück.&lt;br /&gt;
* genType sqrt (genType x)&lt;br /&gt;
: Gibt die Wurzel von x zurück.&lt;br /&gt;
* genType inversesqrt (genType x)&lt;br /&gt;
: Gibt die umgekehrte Wurzel von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standardfunktionen==&lt;br /&gt;
* genType abs (genType x)&lt;br /&gt;
: Liefert den absoluten Wert von x zurück.&lt;br /&gt;
* genType sign (genType x)&lt;br /&gt;
: Gibt -1.0 zurück, wenn x &amp;lt; 0.0, 0.0 wenn x = 0.0 und 1.0 wenn x &amp;gt; 0.0.&lt;br /&gt;
* genType floor (genType x)&lt;br /&gt;
: Gibt denn nächsten Integerwert zurück, der kleiner oder gleich x ist.&lt;br /&gt;
* genType ceil (genType x)&lt;br /&gt;
: Gibt den nächsten Integerwert zurück, der größer oder gleich x ist.&lt;br /&gt;
* genType fract (genType x)&lt;br /&gt;
: Gibt den Nachkommateil von x zurück.&lt;br /&gt;
* genType mod (genType x, float y) &lt;br /&gt;
* genType mod (genType x, genType y)&lt;br /&gt;
: Gibt den Modulus zurück. (=x-y * floor(x/y)) &lt;br /&gt;
* genType min (genType x, genType y) &lt;br /&gt;
* genType min (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn y &amp;lt; x, ansonsten x. &lt;br /&gt;
* genType max (genType x, genType y) &lt;br /&gt;
* genType max (genType x, float y)&lt;br /&gt;
: Liefert y zurück wenn x &amp;lt; y, ansonsten x. &lt;br /&gt;
* genType clamp (genType x, genType minVal, genType maxVal) &lt;br /&gt;
* genType clamp (genType x, float minVal, float maxVal)&lt;br /&gt;
: Zwängt x in den Bereich minVal..maxVal. &lt;br /&gt;
* genType mix (genType x, genType y, genType a)&lt;br /&gt;
* genType mix (genType x, genType y, float a)&lt;br /&gt;
: Liefert den linearen Blend zwischen x und y zurück. (= x * (1-a) + y * a) &lt;br /&gt;
* genType step (genType edge, genType x)&lt;br /&gt;
* genType step (float edge, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge, ansonsten 1.0. &lt;br /&gt;
* genType smoothstep (genType edge0, genType edge1, genType x)&lt;br /&gt;
* genType smoothstep (float edge0, float edge1, genType x)&lt;br /&gt;
: Liefert 0.0 zurück, wenn x &amp;lt;= edge und 1.0 wenn x &amp;gt;= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Geometrie==&lt;br /&gt;
* float length (genType x)&lt;br /&gt;
: Gibt die Länge des Vektors x (= sqrt(x[0]² + x[1]² + ... + x[n]²) zurück. &lt;br /&gt;
* float distance (genType p0, genType p1)&lt;br /&gt;
: Gibt die Distanz zwischen den zwei Vektoren p0 un p1 (= length(p0-p1)) zurück. &lt;br /&gt;
* float dot (genType x, genType y)&lt;br /&gt;
: Gibt das Punktprodukt von x und y zurück (=x[0]*y[0] + x[1]*y[1] + ... + x[n]*y[n]). &lt;br /&gt;
* vec3 cross (vec3 x, vec3 y)&lt;br /&gt;
: Gibt das Kreuzprodukt von x und y zurück. &lt;br /&gt;
* genType normalize (genType x)&lt;br /&gt;
: Normalisiert den Vektor x auf die Länge 1. &lt;br /&gt;
* vec4 ftransform()&lt;br /&gt;
: Nur im Vertex Shader. Die Funktion stellt sicher, das das eingehende Vertex haargenau so transformiert wird wie in der festen Funktionspipeline. gl_Position = ftransform() wird dann also gebraucht, wenn in mehreren Durchgängen sowohl im Shader als auch in der festen Pipeline gerendert wird, um sicherzustellen das in beiden Fällen die gleiche Vertexposition herauskommt. &lt;br /&gt;
* genType faceforward (genType N, genType I, genType Nref)&lt;br /&gt;
: Gibt einen nach vorne zeigenden Vektor N zurück. (If dot(NRef, I) &amp;lt; 0 return N else return -N) &lt;br /&gt;
* genType reflect (genType I, genType N)&lt;br /&gt;
: Gibt den an der Flächenausrichtung N reflektierten Vektor I zurück. (=I-2 * dot(N,I) * N) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Matrixfunktionen==&lt;br /&gt;
* mat matrixCompMult (mat x, mat y)&lt;br /&gt;
: Multipliziert Matrix X mit Matrix Y komponentenweise. Um eine normale lineare Matrixmultiplikation durchzuführen, sollte der &amp;quot;*&amp;quot;-Operator genutzt werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Vektorvergleiche==&lt;br /&gt;
Die meisten Vektorvergleichsfunktionen liefern als Ergebnis einen boolvektor zurück, da die Vergleiche per Komponente stattfinden. Wenn man also x = vec4(1.0, 3.0, 0.0, 0.0) mit y = vec4(2.0, 1.5, 1.5, 0.0) via lessThan(x, y) vergleicht, erhält man als Ergebnis bvec(true, false, true, false).&lt;br /&gt;
&lt;br /&gt;
* bvec lessThan (vec x, vec y)&lt;br /&gt;
* bvec lessThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt; y zurück. &lt;br /&gt;
* bvec lessThanEqual (vec x, vec y)&lt;br /&gt;
* bvec lessThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;lt;= y zurück. &lt;br /&gt;
* bvec greaterThan (vec x, vec y)&lt;br /&gt;
* bvec greaterThan (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt; y zurück. &lt;br /&gt;
* bvec greaterThanEqual (vec x, vec y)&lt;br /&gt;
* bvec greaterThanEqual (ivec x, ivec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x &amp;gt;= y zurück. &lt;br /&gt;
* bvec equal (vec x, vec y)&lt;br /&gt;
* bvec equal (ivec x, ivec y)&lt;br /&gt;
* bvec equal (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x == y zurück. &lt;br /&gt;
* bvec notEqual (vec x, vec y)&lt;br /&gt;
* bvec notEqual (ivec x, ivec y)&lt;br /&gt;
* bvec notEqual (bvec x, bvec y)&lt;br /&gt;
: Gibt den komponentenweisen Vergleich x != y zurück. &lt;br /&gt;
* bool any (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn mindestens eine der Komponenten von x true ist.&lt;br /&gt;
* bool all (bvec x)&lt;br /&gt;
: Liefert true zurück, wenn alle Komponenten von x true sind. &lt;br /&gt;
* bvec not (bvec x)&lt;br /&gt;
: Liefert die logische Negation von x zurück. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Texturenzugriffe==&lt;br /&gt;
&lt;br /&gt;
Diese wichtige Funktionskategorie dient dazu, Werte aus einer an eine Textureinheit gebundenen Textur zu ermitteln. Die Texturenzugriffe können sowohl im Vertex (!) als auch im Fragment Shader ausgeführt werden, wobei der optionale Parameter bias im Vertex Shader ignoriert wird. Allerdings gibt es zusätzlich Funktionen die auf &amp;quot;Lod&amp;quot; enden und nur im Vertex Shader genutzt werden dürfen um eben dieses Manko zu umgehen. Funktionen mit dem Suffix &amp;quot;Proj&amp;quot; geben einen projizierten Texturenwert zurück.&lt;br /&gt;
&lt;br /&gt;
: '''1D-Texturen :'''&lt;br /&gt;
* vec4 texture1D (sampler1D sampler, float coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture1DProj (sampler1D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 texture1DLod (sampler1D sampler, float coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''2D-Texturen :'''&lt;br /&gt;
* vec4 texture2D (sampler2D sampler, vec2 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture2DProj (sampler2D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''3D-Texturen :'''&lt;br /&gt;
* vec4 texture3D (sampler3D sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 texture3DProj (sampler3D sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
* vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Cubemap :'''&lt;br /&gt;
* vec4 textureCube (samplerCube sampler, vec3 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader : &lt;br /&gt;
*vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
: '''Tiefentextur (Shadowmap) :'''&lt;br /&gt;
* vec4 shadow1D (sampler1DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow2D (sampler2DShadow sampler, vec3 coord [, float bias])&lt;br /&gt;
* vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
* vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord [, float bias])&lt;br /&gt;
: Nur im Vertex Shader :&lt;br /&gt;
* vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod)&lt;br /&gt;
* vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
* vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wie bereits eingangs gesagt ist dieses Kapitel ein sehr wichtiges, denn eine 3D-Szene ohne Texturen ist heute kaum denkbar. Darüber hinaus lassen sich durch Texturenzugriffe recht viele interessante Sachen machen, z.B. ein einfacher Blurfilter oder das freie überblenden bestimmter Texturenteile. Deshalb führe ich hier kurz ein paar Beispiele an, welche die Nutzung dieser Funktionen verdeutlichen sollen :&lt;br /&gt;
&lt;br /&gt;
===Beispiel A=== &lt;br /&gt;
Eine Textur gebunden die einfach ausgegeben werden soll&lt;br /&gt;
&lt;br /&gt;
''Im Vertex Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
Der Vertex Shader ist recht minimal. Neben der homogenen Vertexposition leiten wir hier nur die im OpenGL-Programm angegebenen Texturkoordinaten weiter. ''Dies ist aber unbedingt nötig!'' Ohne die letzte Zeile hätten wir im Fragment Shader keine gültigen Texturkoordinaten auf TMU0, was in einer Fehldarstellung enden würde.&lt;br /&gt;
&lt;br /&gt;
''im Fragment Shader'' :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSampler;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_FragColor = texture2D(texSampler, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Zuerst deklarieren wir hier einen 2D-Texturensampler, wichtig : '''Texturensampler müssen IMMER als uniform deklariert werden!''' In der Hauptfunktion weisen wir dann einfach den über die Funktion texture2D aus unserer gebundenen Textur ausgelesenen Farbwert, anhand der vom Vertex Shader übergebenen Texturkoordinaten, zu.&lt;br /&gt;
&lt;br /&gt;
===Beispiel B=== &lt;br /&gt;
Zwei Texturen, jeweils auf TMU0 und TMU1. Fragmentfarbe soll eine Multiplikation der beiden Texturen darstellen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispielfall (der recht häufig vorkommt) müssen wir im Programm festlegen, ''welcher Sampler welche Textureinheit adressiert'', genau deshalb müssen die Texturensampler auch als uniform deklariert werden. Die Standardtextureneinheit eines Samplers ist TMU0, was in unserem Falle natürlich nicht brauchbar ist. Also müssen wir unserem zweiten Textursampler im Programm mitteilen das er seine Daten aus TMU1 beziehen soll :&lt;br /&gt;
&lt;br /&gt;
 glUniform1iARB(glSlang_GetUniLoc(ProgramObject, 'texSamplerTMU1'), 1);&lt;br /&gt;
&lt;br /&gt;
Dies ist also unbedingt zu machen, sobald ein Texturensampler eine Textureinheit &amp;gt; GL_TEXTURE_0 adressieren will. Die Textureneinheit des Samplers lässt sich also nicht im Shader selbst festlegen. Der Fragment Shader ist nun allerdings schnell hergeleitet (Vertex Shader verändert sich nicht, da TMU1 die Texturkoordinaten auch von TMU0 bezieht) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
im Fragment Shader :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D texSamplerTMU0;&lt;br /&gt;
uniform sampler2D texSamplerTMU1;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
    gl_FragColor = texture2D(texSamplerTMU0, vec2(gl_TexCoord[0])) *&lt;br /&gt;
                   texture2D(texSamplerTMU1, vec2(gl_TexCoord[0]));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Noisefunktionen==&lt;br /&gt;
Sowohl im Vertex als auch im Fragment Shader lassen sich [[GLSL noise|Noisefunktionen]] nutzen, mit deren Hilfe sich eine gewisse &amp;quot;Zufälligkeit&amp;quot; simulieren lässt (wirklich zufällige Werte sind es natürlich nicht). Ein zurückgegebener Wert liegt dabei immer im Bereich [-1..1] und ist immer bei gleichem Eigabewert auch immer gleich. Die Verwendung empfiehlt sich derzeit allerdings eher nicht, da nicht alle aktuellen Treiber die Funktionen unterstützen und eine Noisetextur wahrscheinlich performanter ist.&lt;br /&gt;
&lt;br /&gt;
* float noise1 (genType x)&lt;br /&gt;
* vec2 noise2 (genType x)&lt;br /&gt;
* vec3 noise3 (genType x)&lt;br /&gt;
* vec4 noise4 (genType x)&lt;br /&gt;
&lt;br /&gt;
==Discard==&lt;br /&gt;
Eigentlich keine Funktion, sondern eine Abbruchbedingung '''nur im Fragment Shader'''. Das Schlüsselwort {{INLINE_CODE|discard}} verwirft das aktuell bearbeitete Fragment und beendet gleichzeitig den Shader. Es kann z.B. genutzt werden um Alphamasking manuell durchzuführen.&lt;br /&gt;
Man sollte dabei jedoch beachten dass ein Großteil der aktuellen Hardware kein &amp;quot;early-out&amp;quot; (frühes Beenden) im Fragmentshader unterstützt. Wenn dort also ein {{INLINE_CODE|discard}} auftaucht, wird trotzdem auch der Code danach ausgeführt und einfach verworfen. Einen Geschwindigkeitsvorteil durch diesen Befehl wird man also erst auf neueren Karten feststellen, die dieses Faeature auch so unterstützen wie es angedacht war. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Beispielshader=&lt;br /&gt;
Wen bis hierhin nicht der Mut verlassen hat, und wer aufmerksam gelesen hat, dürfte jetzt also zumindest in der Lage sein kleinere Shader in glSlang zu schreiben und diese auch im Programm zu nutzen. Ich habe im Themenbereich &amp;quot;glSlang&amp;quot; versucht alle Bereiche der Shadersprache selbst anzusprechen und hoffe das auch brauchbar rübergebracht zu haben. Um oben erlerntes (hoffe ich doch mal) nochmal zu vertiefen werde ich jetzt (wie ich das bereits bei meinem ARB_VP-Tutorial getan habe) einen simplen Beispielshader (Vertex und Fragment Shader) auseinanderpflücken um so u.a. auch die Programmstruktur für alle die in C nicht so bewandert sind zu erörtern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Vertex Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform vec4 GlobalColor;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
 gl_FrontColor   = gl_Color * GlobalColor;&lt;br /&gt;
 gl_TexCoord[0]  = gl_MultiTexCoord0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie gesagt recht simpel. Angefangen wird mit der Deklaration einer globalen Uniformvariable namens {{INLINE_CODE|GlobalColor}}. Wie wir uns erinnern gibt der Typenqualifizierer uniform an, das wir den Wert dieser Variable (ein 4-Komponentenvektor, da Farbwerte aus R,G,B und A bestehen) in unserem Programm an den Shader übermitteln.&lt;br /&gt;
&lt;br /&gt;
Danach gehts ohne Umwege direkt in unsere Hauptfunktion, da wir im Vertex Shader keine anderen Funktionen benötigen. Dort berechnen wir zuerst die homogene Position unseres Vertex, die sich aus der eingehenden Vertexposition multipliziert mit der Modelansichtsmatrix ergibt. Wie schonmal gesagt '''muss diesem Wert etwas zugewiesen werden''', da sonst alle darauf aufbauenden Funktionen unvorhersehbare Ergebnisse liefern.&lt;br /&gt;
Ausserdem wollen wir die Frontfarbe unseres Vertex jedesmal mit der im Programm übergebenen GlobalColor multiplizieren, so dass wir den Farbwert der gesamten Szene aus unserem Programm heraus manipulieren können. Zu guterletzt geben wir dann noch unsere aus der festen Funktionspipeline erhaltenen Texturkoordinaten auf Textureinheit 0 weiter. Wenn im Fragmentshader Texturkoordinaten verwendet werden, '''muss das getan werden'''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Der Fragment Shader==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
uniform sampler2D Texture1;&lt;br /&gt;
uniform sampler2D Texture2;&lt;br /&gt;
uniform sampler2D Texture3;&lt;br /&gt;
&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
 vec2 TexCoord = vec2( gl_TexCoord[0] );&lt;br /&gt;
 vec4 RGB      = texture2D( Texture0, TexCoord );&lt;br /&gt;
&lt;br /&gt;
 gl_FragColor  = texture2D(Texture1, TexCoord) * RGB.r +&lt;br /&gt;
                 texture2D(Texture2, TexCoord) * RGB.g +&lt;br /&gt;
                 texture2D(Texture3, TexCoord) * RGB.b;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier passiert nicht wirklich viel Großartiges. Wir deklarieren beim Shaderanfang zuerst vier Texturensampler, da wir insgesamt vier verschiedene Texturen im Shader auslesen wollen, eine Verlaufstextur und drei Oberflächentexturen. Auch hier sei wieder gesagt das man Sampler '''immer als uniform deklarieren muss'''. In der Hauptfunktion deklarieren wir dann einen Farbvektor, der auch direkt einen Farbwert aus Textureinheit 0 zugewiesen bekommt. Auf Textureinheit 0 haben wir ihm Hauptprogramm eine Verlaufstextur gebunden, die angibt wie die drei folgenden Texturen ineinander geblendet werden.&lt;br /&gt;
Danach schreiben wir dann den Farbwert des Fragmentes, der '''im Fragment Shader ausgegeben werden muss'''. Der besteht wie einfach zu erkennen aus Farbwert von Textureinheit 1 * Rotwert von Textureinheit 0 + Farbwert von Textureinheit 2 * Grünwert von Textureinheit 0 + Farbwert von Textureinheit 3 * Blauwert von Textureinheit 0. So ist z.B. an Stellen an denen in der Verlaufstextur reines blau liegt nur die dritte Textur sichtbar.&lt;br /&gt;
&lt;br /&gt;
So viel also zu unserem kleinen Beispielshader. Er ist weder besonders toll noch besonders sinnvoll, sollte aber auch eher dazu dienen euch glSlang ein wenig zu veranschaulichen, was mir hoffentlich gelungen ist.&lt;br /&gt;
&lt;br /&gt;
Wenn ihr in den vorangegangenen Kapiteln zumindest ein wenig aufgepasst habt, dann könnt ihr euch vor eurem inneren Auge hoffentlich vortstellen was der Shader macht : Er blendet drei Texturen weich anhand der Verlaufstextur ineinander über. Sowas kann man z.B. für ein Terrain nutzen, um dieses anhand einer Farbtextur zu texturieren. Für alle, die damit Probleme haben hier zwei Bilder die den Shader veranschaulichen. Links die Verlaufstextur, die angibt wo welche Textur wie stark gewichtet wird und rechts dann das Ergebnis :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt; [[BILD:GLSL_sample_shader_a.jpg]] [[BILD:GLSL_sample_shader_b.jpg]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Post Mortem=&lt;br /&gt;
Das wars also, meine &amp;quot;Einführung&amp;quot; in die OpenGL Shader Sprache. Ich hoffe es hat euch nicht gelangweilt und auch die von mir zur Verfügung gestellten Informationen haben euch hoffentlich ausgereicht. Mit der Veröffentlichung dieser Einführung geht übrigens auch die Eröffnung eines Shaderforums hier auf der DGL einher, in der ihr dann also fleissig Fragen zum Thema stellen oder eure Shader präsentieren könnt. In diesem Post Mortem gehe ich jetzt noch kurz auf die Zukunft von glSlang ein und zeige ein paar Screenshots (damit die Augen entspannen können), bevor ihr euch dann selbst in die Shaderwelt stürzen könnt. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Screenshots=&lt;br /&gt;
&lt;br /&gt;
Um eure Augen ein wenig zu verwöhnen und zu zeigen was man mit glSlang alles machen, v.a. da man jetzt Shader schön lesbar in einer Hochsprache verfassen kann, mal ein paar Screens. Besonders der zweite Shot sieht animiert noch besser aus :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[BILD:GLSL_sample_Kugel.jpg]] [[BILD:GLSL_sample_Alien.jpg]] &amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Zahl möglicher Effekte ist bei einer so flexiblen Shadersprache natürlich nahezu unbegrenzt, und besonders auf kommender Hardware werden bisher ungesehen Effekte den Einzu in die Echtzeitgrafik finden. Man darf also mehr als gespannt sein.&lt;br /&gt;
&lt;br /&gt;
=Die Zukunft=&lt;br /&gt;
Viele werden sich sicherlich fragen, warum sie z.B. statt ARB_VP/FP oder Nvidias cG denn überhaupt auf glSlang setzen sollen. Doch solche Zweifel dürften bei einem genauen Blick auf die neue Shadersprache schnell verworfen sein. Zum einen steckt hinter glSlang dank des ARBs fast die komplette 3D-Industrie und zum anderen hat man beim Entwurf der Shadersprache, wie z.B. an vielen reservierten Wörtern/Funktionen erkennbar versucht so weit wie möglich in die Zukunft zu planen. So sollen auch Karten der nächsten und übernächsten Generation mit glSlang ausnutzbar sein, und was danach kommt wird durch Spracherweiterungen erreicht. Sich also jetzt (besonders da es krachneu ist) mit glSlang zu befassen, um nicht ganz den Anschluss an kommende Entwicklungen im 3D-Bereich zu verlieren, ist der beste Weg.&lt;br /&gt;
&lt;br /&gt;
Also viel Spaß beim Experimentieren und Shaderschreiben! Und nicht vergessen : Wir wollen sehen was ihr so treibt,&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:Sascha Willems&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|-|[[Tutorial_glsl2]]}}&lt;br /&gt;
[[Kategorie:Tutorial|GLSL]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Team&amp;diff=24769</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Team&amp;diff=24769"/>
				<updated>2010-03-15T08:26:12Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Moderatoren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Vorwort =&lt;br /&gt;
&lt;br /&gt;
Auf dieser Seite befindet sich eine Auflistung der Personen, die momentan aktiv daran arbeiten, dass DGL Euch wie gewohnt im Netz mit Informationen versorgt. Bitte beachtet, dass die meisten der Personen nur einen begrenzten Vorrat an Zeit haben. Überlegt daher bitte sorgsam, an wen Ihr Euch wendet.&lt;br /&gt;
&lt;br /&gt;
Im unteren Teil dieser Seite sind die verschiedenen Bereiche von DGL und deren Betreuer aufgelistet. Bitte wendet auch an den passenden Ansprechpartner.&lt;br /&gt;
&lt;br /&gt;
Diese Seite ersetzt nicht das '''[http://www.delphigl.com/launcher.php?em=impressum IMPRESSUM]'''.&lt;br /&gt;
&lt;br /&gt;
= Das Team im Ganzen =&lt;br /&gt;
In diesen Abschnitt ist aufgelistet '''wer''' bei [[DelphiGL]] Verantwortung für einen Teil übernommen hat, und '''was''' genau er macht.&lt;br /&gt;
== Moderatoren ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;80%&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;|Forumsname&lt;br /&gt;
!width=&amp;quot;30%&amp;quot;|Email&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Aufgabenbereich&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Phobeus|Phobeus]] &lt;br /&gt;
|{{eMail|Phobeus|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Technische Pflege des Wikis (Wartung/Updates)&lt;br /&gt;
*Betreuung der Hardware&lt;br /&gt;
*Freischalten von Usern für das Forum&lt;br /&gt;
*Freischalten von Usern für das Wiki&lt;br /&gt;
*''News eintragen''&lt;br /&gt;
*''allgemeine inhaltliche Kontrolle''&lt;br /&gt;
*&amp;quot;der Boss&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Flash|Flash]] &lt;br /&gt;
|{{eMail|Flash|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Inhaltliche Pflege/Koordination des Wikis&lt;br /&gt;
*Community-Aktionen&lt;br /&gt;
*Tutorial Lektor&lt;br /&gt;
*DGL-Poll pflegen&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle im Forum&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Frase|Frase]] &lt;br /&gt;
|{{eMail|Frase|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Technische Unterstützung für Phobeus&lt;br /&gt;
*Tutorial Lektor&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle im Forum&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Delphic|Delphic]] &lt;br /&gt;
|{{eMail|delphic|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Freischalten von Usern für das Forum&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Flo|Flo]]&lt;br /&gt;
|{{eMail|Flo|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
*DGL-Wiki-Bot Manager&lt;br /&gt;
*Freischalten von Usern für das Wiki&lt;br /&gt;
*Tutorial Lektor&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:I0n0s|i0n0s]] &lt;br /&gt;
|{{eMail|i0n0s|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
* DGLSDK&lt;br /&gt;
* Freischalten von Usern für das Forum&lt;br /&gt;
* Freischalten von Usern für das Wiki &lt;br /&gt;
* Tutorial Lektor&lt;br /&gt;
* News eintragen&lt;br /&gt;
* allgemeine inhaltliche Kontrolle&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Sascha Willems|Sascha Willems]] &lt;br /&gt;
|{{eMail|webmaster|delphigl.de}}&lt;br /&gt;
|&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle&lt;br /&gt;
*Freischalten von Usern für das Wiki &lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lord_Horazont|Lord Horazont]] &lt;br /&gt;
|{{eMail|lord_horazont|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
*SVN/WebSVN Betreuung&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle&lt;br /&gt;
*Freischalten von Usern für das Forum&lt;br /&gt;
*Freischalten von Usern für das Wiki&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Gruppen =&lt;br /&gt;
In diesem Teil findet ihr detailierte Informationen, wer für welchen Bereich zuständig ist.&lt;br /&gt;
== DGLSDK ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;80%&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;|Forumsname&lt;br /&gt;
!width=&amp;quot;30%&amp;quot;|Email&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Aufgabenbereich&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:I0n0s|i0n0s]] &lt;br /&gt;
|{{eMail|i0n0s|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DGLOpenGL.pas ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;80%&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;|Forumsname&lt;br /&gt;
!width=&amp;quot;30%&amp;quot;|Email&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Aufgabenbereich&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lossy eX|Lossy eX]] &lt;br /&gt;
|{{eMail|Lossy|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Weiterentwicklung, Debugging&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Webseite ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;80%&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;|Forumsname&lt;br /&gt;
!width=&amp;quot;30%&amp;quot;|Email&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Aufgabenbereich&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Phobeus|Phobeus]] &lt;br /&gt;
|{{eMail|Phobeus|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Technische Pflege des Seite (Wartung/Updates)&lt;br /&gt;
*Coding (Integrieren von Neuerungen)&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lord_Horazont|Lord Horazont]]&lt;br /&gt;
|{{eMail|lord_horazont|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
*PHP&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Flash|Flash]] &lt;br /&gt;
|{{eMail|Flash|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*DGL-Poll pflegen&lt;br /&gt;
|-&lt;br /&gt;
|Alle Anderen &lt;br /&gt;
|(siehe oben)&lt;br /&gt;
|&lt;br /&gt;
*News&lt;br /&gt;
*Sorgen für angemessene Umgangsformen&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wiki ==&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;80%&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;|Forumsname&lt;br /&gt;
!width=&amp;quot;30%&amp;quot;|Email&lt;br /&gt;
!width=&amp;quot;50%&amp;quot;|Aufgabenbereich&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Flash|Flash]] &lt;br /&gt;
|{{eMail|Flash|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Inhaltliche Pflege des Wikis&lt;br /&gt;
*Koordinierung&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Phobeus|Phobeus]] &lt;br /&gt;
|{{eMail|Phobeus|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*Technische Pflege des Wikis (Wartung/Updates)&lt;br /&gt;
*Betreuung der Hardware&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:I0n0s|i0n0s]] &lt;br /&gt;
|{{eMail|i0n0s|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
*Filesektion&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lord_Horazont|Lord Horazont]]&lt;br /&gt;
|{{eMail|lord_horazont|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
*Filesektion (SVN Betreuung)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=GLSL_Licht_und_Schatten&amp;diff=24696</id>
		<title>GLSL Licht und Schatten</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=GLSL_Licht_und_Schatten&amp;diff=24696"/>
				<updated>2010-02-10T15:12:13Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Offline entfernt, Artikel nicht mehr in Bearbeitung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Vorwort==&lt;br /&gt;
&lt;br /&gt;
Willkommen zu meinem erstem Tutorial. Schatten können sowohl Traum als auch Albtraum eines jeden OpenGL-Progrmamieres werden. Im Gegensatz zur einfachen Beleuchtung mit Lichtquellen, steigt der Rechenaufwand hier extrem an und ohne Optimierung zwingen die Schatten selbst die modernste Hardware in die Knie.&lt;br /&gt;
Für Schatten gibt es zwei praktikable Algoritmen: Den Stencilschatten und den projezierten Schatten. Hier möchte ich mich auf den projezierten Schatten beschränken, er bietet gegenüber dem Stencilschatten einige Vorteile:&lt;br /&gt;
&lt;br /&gt;
*Die komplette Berechnung kann von der Grakfikkarte übernommen werden&lt;br /&gt;
*Es ist möglich Softshadows zu realisieren&lt;br /&gt;
*Die Shadowmaps können unter Umständen für mehr als ein Frame verwendet werden&lt;br /&gt;
&lt;br /&gt;
Um den Rechenaufwand zu veringern werde ich hier zusätzliche Projektionstechniken zeigen, die über den Vertexshader realisiert werden: Die perspektivische Map und das parabolide Mapping. &lt;br /&gt;
&lt;br /&gt;
Für sehr weit entfernte Lichtquellen und offene Szenen ist der Einsatz von perspektisch angepassten Maps sinvoll. Da das Licht quasi parallel ausgestrahlt wird. Ist ein winkelabhängiger Cube oder dualparabolische Map kaum möglich. Auch eine einfache quadratische Shadowmap zeigt deutliche Schwächen bei der Auflösung im Nahbereich und dem zu hohem Oversampling in der Entfernung.&lt;br /&gt;
&lt;br /&gt;
Das parabolide Mapping ermöglicht nicht nur die Simulation eine Fischaugenoptik, sondern kann auch die Cubemap vollständig ersetzen. Durch einen geringfügig höheren Rechen- und Programieraufwand genügen zwei Renderpasses um eine vollständige Tiefen- oder Reflektionsmap zu erstellen. Was gegenüber der klassischen Cubemap den Prozessor und GPU um den Faktor 3 entlastet.&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Dieses Tutorial basiert auf den grundlegenden Techniken, die erst in den letzten Jahren entwickelt wurden. Jeder der hier mit anfängt, sollte die zwei anderenen GLSL Tutorials gelesen haben und einfache Fragmentshader schreiben können. Auch das Laden und Einbinden von Texturen in die Shader sollte kein Problem mehr darstellen.&lt;br /&gt;
&lt;br /&gt;
===Framebufferobjekte===&lt;br /&gt;
Für das Erstellen von dual paraboliden Tiefentexturen ist noch das Rendern in Framebufferobjekten Vorraussetzung (zu denen es leider noch kein Tutorial gibt). Damit der Einstieg nicht zu schwer wird sollte dieser Code helfen das FBO zu initialsisieren:&lt;br /&gt;
&lt;br /&gt;
Als Erstes müssen die nötigen Extensions initialisiert werden&lt;br /&gt;
Dann sollten die benötigten Modelle als VBO in die Grafikkarte hochgeladen werden.&lt;br /&gt;
Nun muss das Framebufferobjekt (FBO) für die Schattenmaps erzeugt werdern.&lt;br /&gt;
So könnte die Initialsierung des FBOs aussehen. C code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;GLuint shadow_map = 0; // &lt;br /&gt;
GLuint shadow_fbo = 0; // the shadow texture&lt;br /&gt;
GLuint shadow_size = 4096; //muss kleiner/gleich maximaler 2D-Texturgröße sein&lt;br /&gt;
&lt;br /&gt;
glGenTextures (1, &amp;amp;shadow_map); //In Pascal das &amp;amp; durch ein @ ersetzten&lt;br /&gt;
glBindTexture (GL_TEXTURE_2D, shadow_map);&lt;br /&gt;
glTexImage2D (GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, shadow_size, shadow_size, 0,GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE, NULL);&lt;br /&gt;
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
&lt;br /&gt;
glGenFramebuffersEXT (1, &amp;amp;shadow_fbo); //In Pascal das &amp;amp; durch ein @ ersetzten&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fbo);&lt;br /&gt;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,shadow_map, 0);&lt;br /&gt;
glDrawBuffer (GL_FALSE);&lt;br /&gt;
glReadBuffer (GL_FALSE);&lt;br /&gt;
GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); //noch ein wenig Code anfügen um den Status zu überprüfen.&amp;lt;/source&amp;gt;&lt;br /&gt;
Pascal :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var &lt;br /&gt;
  shadow_map,&lt;br /&gt;
  shadow_fbo,&lt;br /&gt;
  shadow_size : TGLuint;&lt;br /&gt;
  status      : TGLenum; &lt;br /&gt;
begin&lt;br /&gt;
  shadow_size := 4096; // muss kleiner/gleich maximaler 2D-Texturgröße sein&lt;br /&gt;
&lt;br /&gt;
  glGenTextures(1, @shadow_map);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, shadow_map);&lt;br /&gt;
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadow_size, shadow_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NIL);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
&lt;br /&gt;
  glGenFramebuffersEXT(1, @shadow_fbo);&lt;br /&gt;
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo);&lt;br /&gt;
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow_map, 0);&lt;br /&gt;
  glDrawBuffer (GL_FALSE);&lt;br /&gt;
  glReadBuffer(GL_FALSE);&lt;br /&gt;
  Status := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); //noch ein wenig Code anfügen um den Status zu überprüfen.&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
Jetzt sollten die Shader und weiter Texturen geladen werden.&lt;br /&gt;
&lt;br /&gt;
===Beschleunigtes Rendern===&lt;br /&gt;
&lt;br /&gt;
Ich empfehle auch die zu rendernden Daten als Vertexbufferobjekte zu übergeben, da sonst die Mehrfachverwendung der Daten zu einer extremen Bremse wird. Da es hierzu bereits ein Tutorial gibt werde ich hier nichts mehr darüber schrieben.&lt;br /&gt;
Alternativ sollte alles was zwischen glBegin und glEnd in Displaylisten gespeichter werden. Das Speichern von Texturwechseln usw ist nicht sinvoll, da diese nicht zum Rendern der Shadowmaps benötig werden.&lt;br /&gt;
&lt;br /&gt;
Bei mehrfachen Lichquellen kann es wiederum Sinn machen den ersten Rendervorgang inclusive Shaderwechsel in einer Displayliste zwischenzuspeichen und die zusätzlichen Schadowmaps mit dieser zu rendern.&lt;br /&gt;
&lt;br /&gt;
===Algemeines zu GLSL===&lt;br /&gt;
Ich möchte nocheinmal darauf hinweisen, das sich uniformvariablen nur setzten Lassen, wenn der entsprechnde shader gebunden ist. (Es funktionier nicht wenn der shader nicht gebunden ist. Warum man den shader dabei allerdings angeben muss ist mir nicht so ganz klar)&lt;br /&gt;
In den Beispielen werden nur die Uniformvariablen wärend des Rendervorgangs neu gesetzt die sich ändern.  Die zuweisung der TMU zu einem Sampler gehöhrt in der Regel nicht dazu. &lt;br /&gt;
&lt;br /&gt;
===Grundlegendes zu den Koordinatensystemen in den Shadern===&lt;br /&gt;
&lt;br /&gt;
Im Vertexshader müssen alle komponenten von gl_Position in einem Bereich von -1.0 bis 1.0 gebracht werden. Besonders beim Z-Wert könnte es verwirrend, dass der Bereich  von gl_FragDepth im Fragmentshader von 0.0 bis 1.0 geht. Auch muss beachtet werden, dass Texturkordinaten den bereich von 0.0 bis 1.0 nutzen, wärend die Rendertargets im Bereich on -1.0 bis 1.0 arbeiten.&lt;br /&gt;
In den Shadern werden daher öfters Multimplikationen mit 0.5 und einer anschließenden Addition von 0.5 auftreten.&lt;br /&gt;
&lt;br /&gt;
==Perspektivische Maps==&lt;br /&gt;
&lt;br /&gt;
In dem erstem Teil dieses Artikels geht es um perspektivisch angepasste Schattenmaps. Normale projezierte Schatten haben das Problem, das sie im Nahenbereich besonders stark verpixeln und in der Entfernung durch ein viel zu hohes Oversampling Bandbreite verschwenden.&lt;br /&gt;
&lt;br /&gt;
Für eine globale Lichquelle wird nur ein Vektor gegeben, der die Richtung des Lichtes beschreibt. Die gedachte Lichtquelle ist quasi unendlich weit weg. Da eine Entfernungsberechnung zur Lichquelle unmöglich ist, muss die Schattenberechnung relativ zu einer Referenzebene durchgeführt werden. Diese Ebene kann sowohl Senkrecht zum Lichvektor, als auch parallel zum gedachtem Boden ausgerichtet werden. Die Ausrichtung der Referenzebene beeinflusst die später sichtbare Auflösung der Schatten.&lt;br /&gt;
&lt;br /&gt;
Nach dem ein Vertex auf die Ebene projeziert wurde und der Abstand ein einen berech von 0.0...1.0 gebracht wurde, muss diese unendlich große Ebene noch auf eine endliche Größe projeziert werden, die auf eine Textur passt und die entfernungsabhängige Detailierung beachtet.&lt;br /&gt;
&lt;br /&gt;
Wenn wir unsere Referenzebene einfachhalber den Horizont schneidet (und auch den Bildschirm in obere und untere Hälfte teilt) Könnte ein Algorimus in etwa so aussehen (Dieser lässt sich später in ein Vertexshaderprogramm umsetzten):&lt;br /&gt;
&lt;br /&gt;
Projeziere den Vertex in die Modelview (Diese Schritt wurde auch bei den dualparaboliden Maps durchgeführt)&lt;br /&gt;
Ermittel den Schnittpunt des vom Vertex ausgehendem gedachtem Lichtstrahl und der Referenzebene.&lt;br /&gt;
Benutze den Abstand zwischen Schnittpunkt und Vertex um den Z-Wert zu ermitteln. (Es sind zwei zusätzlich referenzwerte nötig die die funktion Farclip und Nearclip übernehmen)&lt;br /&gt;
Projeziere die Ebene auf eine Ebene die in eine Textur passt pos/=abs(pos)+1.0 passt recht gut.&lt;br /&gt;
Anschließend wird noch die Schadowmap noch gestreckt und der Bereich hinter der Kammera entfernt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste ist, dass beim auswerten der shadowmaps der gleiche Projektionsalgoritmus verwendet wird wie beim generieren.&lt;br /&gt;
&lt;br /&gt;
Prinzipell sollte sich der Algoritmus schon auf einer Geforce 3 oder Radeon 8500 implementieren lassen. Da da der Code hier in GLSL geschrieben ist, sollte in etwa Shadermodel 2.0 unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
Geschwindigkeitsmäßig ist dieser Algoritmus den Stencilshadows deutlich überlegen. Auch bei Stencilshadows sind mehrere Renderpasses nötig. Vorallem das extruieren der Siluetten kostet einiges an Bandbreite. Der geschätzte Aufwand ist etwa 20 (Aufwendige Shader im Finalem Renderdurchgang)bis 80% (CPU limitiert Geometrieübergabe) Mehraufwand gegenüber einer Schattenlos gerenderten Scene.&lt;br /&gt;
Auch die Qualität ist nicht schlechter. Bei der Verwendung von weichen Schatten wirken Shadowmaps natürlicher als die extrem scharfen Stencilshadows. &lt;br /&gt;
&lt;br /&gt;
===Hauptprogramm===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife könnte folgender Code verwendet werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
	glBindTexture(GL_TEXTURE_2D, 0 ); //Entfernt alle Texturen aus der ersten TMU&lt;br /&gt;
	glUseProgramObjectARB(shadow); //lädt den Schattenshader&lt;br /&gt;
	glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fb); //Bindet das Framebufferobjekt&lt;br /&gt;
	&lt;br /&gt;
	glViewport (0, 0,shadow_sz,shadow_sz); //Anpassen des Viewportes &lt;br /&gt;
	glClear(GL_DEPTH_BUFFER_BIT); //Z-Buffer löschen&lt;br /&gt;
	&lt;br /&gt;
	render(); //Erster Renderdurchgang&lt;br /&gt;
&lt;br /&gt;
	glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); //Normalen Framebuffer binden&lt;br /&gt;
	glBindTexture(GL_TEXTURE_2D, shadow_tx ); //Tiefenmap an die erste TMU binden&lt;br /&gt;
	glUseProgramObjectARB(final); //finalen shader binden&lt;br /&gt;
	&lt;br /&gt;
	glViewport(0, 0, screen_size_x, screen_size_y);&lt;br /&gt;
	&lt;br /&gt;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Color und Z-Buffer löschen&lt;br /&gt;
	render(); //rendern&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Shader===&lt;br /&gt;
&lt;br /&gt;
Als erstes der Vertexshader zum generieren der Schadowmap. shadow.vert:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void){&lt;br /&gt;
&lt;br /&gt;
	vec3 lightdir = gl_NormalMatrix * normalize(vec3(0.1,-1.0,0.0)); //Lichtvektor in den Modelsprace rotieren&lt;br /&gt;
	vec3 mvertex =  vec3 (gl_ModelViewMatrix * gl_Vertex); //Vertex in den Modelspace projezieren&lt;br /&gt;
	vec2 pos = mvertex.xz + lightdir.xz * -mvertex.y/lightdir.y; //Schnittpunkt mit der XZ Referenzebene&lt;br /&gt;
	pos = pos / (abs(pos)+1.0); //Projektion der Ebene auf ein Quadrat&lt;br /&gt;
	pos = pos * vec2(1.0,1.8) + vec2(0.0,0.8); //Abschneiden des Bereiches hinter der Kammera&lt;br /&gt;
	gl_Position.xy = pos;&lt;br /&gt;
	gl_Position.z = -mvertex.y ; // Der Bereich von +-1 über der Referenzebene wird erfasst&lt;br /&gt;
	gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
 	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Lichtrichtung wird vorläufig noch fest übergeben. Eine Auswertung einer Opengl Lichtquelle oder einer Uniformvariable wäre ebenfalls möglich. Anschließend wird der Vertex in die Modelview projeziert und der Schnittpunkt des vom Vertexausgehendem Lichstrahls mit der Referenszebene berechnet. Als letztes wird noch der Abstand zur Referenzebenein einem Bereich 0..1  umgerechnet und die Texturkoordinaten für eventuelles Alphamasking oder Heightmapping durchgeschleift. Soll Alphamasking verwendet werden, muss ein entsprechender Shader geschrieben werden der bei den freizulassenden pixeln discard(); aufruft. Dies sollte jedoch nur für die betroffenen Poligone stat finden, da die Grafikkarte dann keine Early-Z Optimierungen verwenden kann. Ansonsten ist der Fragmentshader ist sehr einfach: shadow.frag:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void){}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die für die Auswertung müssen wir im finalem Renderdurchgang exakt die gleichen Texturkoordinaten für die Shadowmap generieren. Allerdings gibt es eine Besonderheit: Die koordinaten einer Textur reichen von 0;0 bis 1;1, Die Koordinaten eines Rendertargets reichen jedoch von -1;-1 bis 1;1, so das eine zusätzliche korrektor nötig ist.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 spos;&lt;br /&gt;
&lt;br /&gt;
void main(void){&lt;br /&gt;
        vec3 lightdir = gl_NormalMatrix * normalize(vec3(0.1,-1.0,0.0));&lt;br /&gt;
        vec3 mvertex =  vec3 (gl_ModelViewMatrix * gl_Vertex);&lt;br /&gt;
        vec2 pos = mvertex.xz + lightdir.xz * -mvertex.y/lightdir.y;&lt;br /&gt;
        pos = pos / (abs(pos)+1.0);&lt;br /&gt;
        pos = pos * vec2(1.0,1.8) + vec2(0.0,0.8); //Abschneiden des Bereiches hinter der Kammera&lt;br /&gt;
        pos = pos * 0.5 + 0.5; //auf Texturkoordinaten umrechnen&lt;br /&gt;
 &lt;br /&gt;
        spos.xy = pos; //Daten in einer Varying verpacken&lt;br /&gt;
        spos.z = -mvertex.y * 0.5 + 0.5 - 0.005; // far and near clamping and Anti-Z-fighting-offset &lt;br /&gt;
 	&lt;br /&gt;
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; //Die echte Transformation&lt;br /&gt;
 &lt;br /&gt;
        gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
        gl_TexCoord[1] = gl_MultiTexCoord1;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ersten 5 Zeilen der main() sollten exakt das gleiche tun wie der Vertexshader zum gnerieren der Map.&lt;br /&gt;
&lt;br /&gt;
Nun fehlt noch ein Fragmentshader für den letzten Durchgang:&lt;br /&gt;
&lt;br /&gt;
Es muss noch der Noralvektor berücksichtigt werden!!!&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Shadowmap;&lt;br /&gt;
varying vec3 spos;&lt;br /&gt;
 &lt;br /&gt;
void main(void){&lt;br /&gt;
        if (texture2D(Shadowmap, spos.xy).r &amp;gt; spos.z ){&lt;br /&gt;
              //Licht&lt;br /&gt;
              gl_FragColor = vec4(1.0,1.0,1.0,1.0);&lt;br /&gt;
              }&lt;br /&gt;
        else{&lt;br /&gt;
              //Schatten&lt;br /&gt;
              gl_FragColor = vec4(0.5,0.5,0.5,1.0);&lt;br /&gt;
              }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parabolide Maps==&lt;br /&gt;
&lt;br /&gt;
Einfache parabolide Maps können für alle Punktlichquellen verwendet werden, deren Licht nicht in alle Richtungen abgestrahlt wird. Darunter fallen vorallem Spots und an Wänden oder Decken befestigte Lampen. Im gegensatz zur Paralelem Licht oder einer Punktlichquelle bringt eine solche Lichtquelle häufig eine Helligkeitsmap mit. Für die Helligkeitsmap und die Schattenmap können die gleichen Texturkoordinaten verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Bei kleinen Öffnungswinkeln hat die parabolide Map keinen Vorteil gegenüber einer normalen Projektion. Der Vortiel ist jedoch das der Code sich für Öffnungswinkel von bis zu ~240 Grad eignet. &lt;br /&gt;
&lt;br /&gt;
Um eine solche Lichquelle zu beschreiben weden nicht weniger als drei Vektoren benötigt:&lt;br /&gt;
&lt;br /&gt;
* Position&lt;br /&gt;
* Richtung &lt;br /&gt;
* Tangent&lt;br /&gt;
&lt;br /&gt;
Wärend die Funktion der ersten beiden Vektoren klar ist, wird der Tangent wird dazu benötigt die Schattenmap und Helligkeitsmap auszurichten. Er ist Senkrecht zur Richtung tangential zur Textur ausgerichtet &lt;br /&gt;
Beschreiben lässt sich diese Funktion lässte sich am ehesten durch das Verdrehen einer Taschenlampe. Wenn die Schattenmap gegenüber den schattenwerfenden Objekten verdreht wird, sieht das Bild auf keinen Fall mehr natürlich aus.&lt;br /&gt;
 &lt;br /&gt;
Es ist sowohl möglich die Berechnungen im Vertexshader durchzuführen, als auch eine entsprechnede Matrix in den Uniformvariablen abzulegen. Wenn die Berechnungen per Matrix durchgefühert werden lässt sich das Prinzip der paraboliden Maps zuindest als Reflektionsmap nutzen. Ein weiterer Vorteil an einer vorberechneten Matrix ist, dass diese auch für shadowmap verwendet werdne kann die nicht jedes Frame neu berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==Dual Parabolide Maps==&lt;br /&gt;
Von OpenGL kennen wir zwei Projektionsmöglichkeiten: Orthografische und perspektivische Projektion. Beide Projektionen arbeiten ohne Verzerrung. Jede Gerade bleibt beim Transformieren eine Gerade. Wenn man dagegen das Bild eines Fischeyeobjektives betrachtet, allen einem sofort die zu Kurven verzerrten Geraden auf. Der entscheidene Vorteil an einer Fisheyeaufnahme ist, dass ein Öffnungswinkel von 180 Grad erfasst werden kann. Zwei entgegensetzte Aufnahmen können so problemlos den kompletten Raum um die Kamera erfassen.&lt;br /&gt;
&lt;br /&gt;
Für das Erstellen der Tiefenmap ist es notwendig den Raum um das reflektierende Objekt in eine Textur zu rendern. Meistens wird hier eine Cubemap verwendet. Soll diese dynamisch generiert werden, ist es auffällig, dass die Scene ganze 6 mal gerendert werden muss. Mit der dual paraboliden Map sind nur noch zwei Rendervorgänge nötig, es wird zwar keine Füllrate eingespart, dafür müssen nun nur noch 1/3 der Daten transformiert werden, so das die Vertexshader und die CPU entlastet werden.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Optimierung ist unter Umständen möglich: Wenn bei einer Cubemap auf eine der Flächen verzichte werden kann. Z.B. wird die Reflektion im Lack eines Autos so gut wie nie verdeckte Straße zeigen. Auch ist für eine an einer  Wand befestigten Lampe nur eine halbkugelförmige Shadowmap nötig. Wenn sie einen Abstand zur Wand hat, genügt es auch hier den Blickwinkel von 180 Grad etwas zu erweitern.&lt;br /&gt;
&lt;br /&gt;
Die Projektion der dualparaboliden Map kann man sich am besten Bild eines Fisheyobjektives vorstellen. Mathematisch etwas genauer ist das Reflektionsbild der umgebenden Welt in einem Rotationsparaboliden.&lt;br /&gt;
&lt;br /&gt;
Die Hardwareanforderungen an den Pixelshader sind nicht gerade gering. Der Pixelshader für die 8fachen Lichquellen kommt nach dem Compelieren auf über 170 Instruktions. Eine Shader 2.0 Karte wie z.B. die Radeon 9x00 sind hier hoffnungslos überfordert da sie nur an 3 Stellen im Programm auf die Textureinheiten zugreifen können und der Assembler nicht mehr in der Lage ist die Instruktions passend umzusortieren. Noch fataler wird es  wenn die Texturelookups durch dynamisches Branching übersprungen weder sollen: Die Karte hat keine Chance mehr diese umzusortieren.&lt;br /&gt;
&lt;br /&gt;
Wer dualparbolide Maps auf SM2.0 Karten einsetzten will sollte damit rechnen, dass das Limit bei 2 bis 4 Maps liegen sollte.&lt;br /&gt;
&lt;br /&gt;
===Hauptprogramm===&lt;br /&gt;
&lt;br /&gt;
So kann in der Hauptschleife das rendern der 16 paraboliden Maps und der anschließende Finale Renderdurchgang durchgeführt werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;//Shader für Dualparabolische Mpas aktivieren&lt;br /&gt;
glUseProgramObjectARB(parabol);&lt;br /&gt;
&lt;br /&gt;
//Framebufferobjekt aktivieren&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fb);&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
//Die 8 Lichtquellen Rendern&lt;br /&gt;
for (int light;light&amp;lt;8;light++){&lt;br /&gt;
        glViewport (shadow_size/2*(lights/4),shadow_size/4 *(light%4),shadow_size/4,shadow_size/4);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;light&amp;quot;),light);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;renderpass&amp;quot;),0);&lt;br /&gt;
        render();&lt;br /&gt;
        glViewport (shadow_size/4+shadow_size/2*(lights/4), shadow_size/4*(light%4),shadow_size/4 ,shadow_size/4);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;renderpass&amp;quot;),1);&lt;br /&gt;
        render();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
// Framebufferobjekt deaktivieren&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
&lt;br /&gt;
//Richtigen Shader aktivieren&lt;br /&gt;
glUseProgramObjectARB(final);&lt;br /&gt;
//Vieport an Fenstergröße anpassen&lt;br /&gt;
glViewport(0, 0,Windowsize_X,Windowsize_Y);&lt;br /&gt;
&lt;br /&gt;
//Frame rendern&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
render();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ungetesteter Pascalcode:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
//Shader für Dualparabolische Mpas aktivieren&lt;br /&gt;
glUseProgramObjectARB(parabol);&lt;br /&gt;
&lt;br /&gt;
//Framebufferobjekt aktivieren&lt;br /&gt;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fb);&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
//Die 8 Lichtquellen Rendern&lt;br /&gt;
for light := 0 to 7 do&lt;br /&gt;
begin&lt;br /&gt;
  glViewport(shadow_size/2*(lights/4), shadow_size/4 *(light mod 4), shadow_size/4, shadow_size/4);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'light'), light);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'renderpass'), 0);&lt;br /&gt;
  render();&lt;br /&gt;
  glViewport(shadow_size/4+shadow_size/2*(lights/4), shadow_size/4*(light mod 4), shadow_size/4, shadow_size/4);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'renderpass'),1);&lt;br /&gt;
  render();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Framebufferobjekt deaktivieren&lt;br /&gt;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
&lt;br /&gt;
//Richtigen Shader aktivieren&lt;br /&gt;
glUseProgramObjectARB(final);&lt;br /&gt;
//Viewport an Fenstergröße anpassen&lt;br /&gt;
glViewport(0, 0, Windowsize_X, Windowsize_Y);&lt;br /&gt;
&lt;br /&gt;
//Frame rendern&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
render();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die Shader===&lt;br /&gt;
&lt;br /&gt;
====Shader zum Rendern der Schattenmaps====&lt;br /&gt;
parabol.vert&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;  uniform int renderpass;&lt;br /&gt;
  uniform int light;&lt;br /&gt;
  varying vec3 normal;&lt;br /&gt;
  varying vec3 pos;&lt;br /&gt;
&lt;br /&gt;
  void main(void){&lt;br /&gt;
&lt;br /&gt;
	gl_Position = gl_ModelViewMatrix * gl_Vertex - gl_LightSource[light].position ;&lt;br /&gt;
&lt;br /&gt;
	float L= length (gl_Position.xyz);&lt;br /&gt;
	gl_Position /= -L;&lt;br /&gt;
	if (renderpass == 1) gl_Position.z *=-1.0;&lt;br /&gt;
	gl_Position.z += 1.0;&lt;br /&gt;
	gl_Position.xy /= gl_Position.z;&lt;br /&gt;
	if (gl_Position.z &amp;gt;= 0.01){&lt;br /&gt;
		gl_Position.z = L / 15.0;//Todo: optimieren&lt;br /&gt;
		gl_Position.w = 1.0;&lt;br /&gt;
		}&lt;br /&gt;
	else{&lt;br /&gt;
		gl_Position.z = -1.0;&lt;br /&gt;
		gl_Position.w = -1.0;&lt;br /&gt;
		}&lt;br /&gt;
        &lt;br /&gt;
        gl_Position.z = 2.0 * gl_Position.z -1.0; //Todo: optimieren&lt;br /&gt;
	pos=gl_Position.xyz;&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parabol.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 pos;&lt;br /&gt;
void main(void){&lt;br /&gt;
	if (length(pos.xy)&amp;gt;1.005)discard; //Diese Zeile kann durchaus entfallen. Kosten/Nutzen unbekannt.&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Uniformaviablen, die gesetzt werden müssen: Eine ist die Nummer der aktuellen Lichtquelle und die zweite der Renderpass, der angibt ob die Vorder- oder Rückseite der parabolischen Map gerendert werden soll. Eine automatische Berechnung der Texturkoordinaten wäre zwar möglich, jedoch ist die Änderung des Viewports deutlich weniger Rechenaufwendig.&lt;br /&gt;
&lt;br /&gt;
Statt einer Multiplikation des gl_Vertex mit der gl_ModelViewProjektionMatrix wird hier nur mit der gl_ModelViewMatrix multipliziert. Dadurch werden nur die Transformationen durchgeführt und die Projektion übersprungen.&lt;br /&gt;
Die Division durch -L entspricht weitgehend einer Normalsierung, spiegelt die Welt jedoch in die richtige Lage. L enthält jetzt die Tiefeninformation, gl_Position einen Vektor, der von der Kammera auf den Vertex zeigt. Mit den zwei folgenden Zeilen wird der Vektor parabolisch auf die Bildschirmkoordinaten projeziert (Intervall von -1.0 bis 1.0). Mit Hilfe der folgenden if-Abfrage werden alle Vertices hinter der Kammera geclipt. Nur sichtbare Vertices bekommen gültige z Werte für den Zbuffer im Intervall von -1.0 bis 1.0. &lt;br /&gt;
&lt;br /&gt;
Der Fragmentshader ist extrem einfach, da wir aufgrund des nicht vorhandem Colorbuffers keinen Farbwert benötigen lassen wir diesen wie bei den perspektivischen Maps einfach undefiniert.&lt;br /&gt;
Zudem verlassen wir den Shader mit discard, wenn der der Pixel außerhalb der aktuellen paraboliden Map liegt. Die Voteil ist, das nur der kreisförmige Bereich der Map verwendet wird, der Nachteil, das durchaus eine Early-Z optimierung nicht mehr möglich ist. Sehr Sinvoll sollte dies sein, wenn die Shadowmaps dynamisch nach benötigter Größe angeordnet werden. Da sich Kreise besser als Quadrate packen lassen.&lt;br /&gt;
&lt;br /&gt;
====Shader für den finalen Renderdurchgang====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
final.vert&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
&lt;br /&gt;
void main(void){&lt;br /&gt;
	Normal = gl_NormalMatrix * gl_Normal;&lt;br /&gt;
 	ModelVertex  = vec3 (gl_ModelViewMatrix * gl_Vertex);&lt;br /&gt;
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
	gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
 	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
&lt;br /&gt;
uniform sampler2D Texture0; // Eine normale Textur &lt;br /&gt;
uniform sampler2D Shadowmap;  //Damit ist auch die 4. TMU belegt..&lt;br /&gt;
uniform int MaxLights;&lt;br /&gt;
&lt;br /&gt;
//Achtung folgende Zeile ist nicht GLSL konform. &lt;br /&gt;
//Workaround: Array als Uniform übergeben oder durch sehr aufwendige berechnung erstzten&lt;br /&gt;
//Sollte es auch auf ATI Karten funktinieren, frage ich mich warum es nicht erlaubt ist...&lt;br /&gt;
const vec2 texofset[8] = {vec2 (0.125,0.125), vec2 (0.125,0.375), vec2 (0.125,0.625), vec2 (0.125,0.875),&lt;br /&gt;
			  vec2 (0.625,0.125), vec2 (0.625,0.375), vec2 (0.625,0.625), vec2 (0.625,0.875)};&lt;br /&gt;
void main(void){&lt;br /&gt;
	vec4 light=vec4 (0.2, 0.2, 0.2, 0.0); //Emmitiertes Licht&lt;br /&gt;
	vec3 normalvec =normalize(Normal.xyz);&lt;br /&gt;
	for (int LightNum = 0;LightNum &amp;lt; MaxLights; LightNum++){&lt;br /&gt;
		vec3 lightvec = ModelVertex - gl_LightSource[LightNum].position.xyz;&lt;br /&gt;
		vec3 lightdir = normalize( lightvec );&lt;br /&gt;
		vec2 parabol = texofset[LightNum];&lt;br /&gt;
		if (lightdir.z &amp;gt; 0.0){&lt;br /&gt;
			parabol.t += 0.25;&lt;br /&gt;
			}&lt;br /&gt;
                // parabolische Projektion für subtextur&lt;br /&gt;
		parabol -=  lightdir.xy * 0.125/ (abs (lightdir.z) + 1.0); &lt;br /&gt;
		vec4 shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol).r );&lt;br /&gt;
		light += shadow * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&lt;br /&gt;
		}&lt;br /&gt;
	vec4 color = texture2D(Texture0, vec2(gl_TexCoord[0]));	//Textur auslesen; &lt;br /&gt;
	gl_FragColor = light * color ;&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglicher weise für ATI taugliche Variante:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
 &lt;br /&gt;
uniform sampler2D Texture0; // Eine normale Textur &lt;br /&gt;
uniform sampler2D Shadowmap;  //Damit ist auch die 4. TMU belegt..&lt;br /&gt;
const int MaxLights=8;&lt;br /&gt;
 &lt;br /&gt;
vec2 texofset[8]; &lt;br /&gt;
void main(void){&lt;br /&gt;
	texofset[0] = vec2 (0.125,0.125);&lt;br /&gt;
	texofset[1] = vec2 (0.125,0.375);&lt;br /&gt;
	texofset[2] = vec2 (0.125,0.625);&lt;br /&gt;
	texofset[3] = vec2 (0.125,0.875);&lt;br /&gt;
	texofset[4] = vec2 (0.625,0.125);&lt;br /&gt;
	texofset[5] = vec2 (0.625,0.375);&lt;br /&gt;
	texofset[6] = vec2 (0.625,0.625);&lt;br /&gt;
	texofset[7] = vec2 (0.625,0.875);&lt;br /&gt;
&lt;br /&gt;
        vec4 light=vec4 (0.2, 0.2, 0.2, 0.0); //Emmitiertes Licht&lt;br /&gt;
        vec3 normalvec =normalize(Normal.xyz);&lt;br /&gt;
        for (int LightNum = 0;LightNum &amp;lt; MaxLights; LightNum++){&lt;br /&gt;
                vec3 lightvec = ModelVertex - gl_LightSource[LightNum].position.xyz;&lt;br /&gt;
                vec3 lightdir = normalize( lightvec );&lt;br /&gt;
                vec2 parabol = texofset[LightNum];&lt;br /&gt;
                if (lightdir.z &amp;gt; 0.0){&lt;br /&gt;
                        parabol.t += 0.25;&lt;br /&gt;
                        }&lt;br /&gt;
                // parabolische Projektion für subtextur&lt;br /&gt;
                parabol -=  lightdir.xy * 0.125/ (abs (lightdir.z) + 1.0); &lt;br /&gt;
                float shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol).r );&lt;br /&gt;
                light += shadow * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&lt;br /&gt;
                }&lt;br /&gt;
        vec4 color = texture2D(Texture0, vec2(gl_TexCoord[0])); //Textur auslesen; &lt;br /&gt;
        gl_FragColor = light * color ;&lt;br /&gt;
        }&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Shader besitzen 3 Uniformvariablen, die unbedingt mit den richtigen Werten gefüllt werden müssen. Zwei davon sind Texturen, die dritte die Anzahl der aktiven Lichtquellen. Es ist wichtig zu wissen, dass der Shader nicht den OpenGL-Status der Lichquellen berücksichtigt und nur die Daten der Ersten bis MaxLights holt.&lt;br /&gt;
Während bei den Schattenmaps die meiste Arbeit im Vertexshader erledigt werden könnte, ist dieser sehr Fragmentshader lastig. Die Texturkoordinatenberechnung ist sehr ähnlich zu der im shadow.vert. Die größte Änderung ist, dass hier abhängig von der Lichtquellennummer ein Offset aufaddiert wird um die Untertextur auszuwählen. Ein zusätzlicher Offset wird dazuaddiert, wenn auf die zweite parabolide Map einer Lichtquelle zugegriffen wird.&lt;br /&gt;
Um ein dynamisches Branching zu vermeiden, wird mit der Stepfunktion ermittelt ob sich das Fragment im Schatten befindet.&lt;br /&gt;
&lt;br /&gt;
==Optimierungen und Verbesserungen==&lt;br /&gt;
Hier sind noch einige Vorschläge, die helfen können um besser Qualität oder Leistungen im eigenem Programm zu bekommen. Eine uniververselle Lösung lässt sich nur auf kosten von Performance schreiben. Viel besser ist es, wenn man die Shader an die jeweilige Situation anpasst. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Schatten durch Alphatest===&lt;br /&gt;
Der bisherige Schattenshader kann nur ganze Polygone einen Schatten werfen lassen. Wenn shadow.vert so ergänzt wird, das die Texturkoordinaten in den Fragmentshader  weitergereicht werden, dann ist es mit folgendem Fragmentshader möglich Shatten in Abhängikeit einer Alphatextur zu rendern:&lt;br /&gt;
&lt;br /&gt;
shadow.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
        if (texture2D(Texture0,vec2(gl_TexCoord[0])).a &amp;lt; 0.5) discard;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Shader wird verlassen wenn das Texel einen Alphawert von kleiner als 50% hat. Damit lassen sich Schatten von Pflanzen wesentlich realistischer darstellen. Dieser Shader sollte natürlich nur dann verwendet werden, wenn eine Alphakanal in der Textur vorhanden ist. Auch Shader mit Paralax- oder Displacementmapping arbeiten kann man so um einen Schatten ergänzen, wenn die Polygone transparente Teile enthalten.&lt;br /&gt;
Es ist auch möglich den shader zu verlassen, wenn eine bestimmte Farbe in der Textur gefunden wird, dann nimmt die Alphamaske keinen Speicherplatz mehr weg.&lt;br /&gt;
&lt;br /&gt;
===Farbiges Glas===&lt;br /&gt;
&lt;br /&gt;
Schatten hat jetzt ja sachon fast jeder. Aber wie wäre es mal mit einfärben von dynamischen Lichtquellen?&lt;br /&gt;
Der Algoritmus ist nicht schwer:&lt;br /&gt;
&lt;br /&gt;
* Alle Undurchichtigen Sceneteile in die Tiefenmaps gerendert. &lt;br /&gt;
* Zusätzlich wird eine Colormap gebunden und das Schreiben in den Zbuffer unterbunden.&lt;br /&gt;
* Die Colormap wird mit Weiß oder einer Helligkeitsmap initialisiert.&lt;br /&gt;
* Rendern aller transparenten Objekten&lt;br /&gt;
* Auf finales Rendern umschalten&lt;br /&gt;
* Alle undurchsichtigen Objekte mit hilfe der Schadowmap und der modifizierten Beleuchtungmap beleuchten.&lt;br /&gt;
* Alle Transparenten Objekte rendern, unter Berücksichtigung, dass die Lichtquelle bereits das gefilterte Licht aussendet. Dieses Blending sollte rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Bei diesem Algoritmus bleibt noch das Alphablendingproblem mit der mehrfachen Überdeckung. Beim Modifizieren der Beleuchtungsmap gegebenfalls den Stencilbuffer zur Hilfe nehmen. Hier wäre ein denkbarer Algoritmus:&lt;br /&gt;
&lt;br /&gt;
* Alle transparenten Poligone in den Zbuffer rendern. Dabei für alle Poligone, deren  doppelte Filterung zu Fehlern führen kann mit verschiedenen Stencilwerte schreiben.&lt;br /&gt;
* Zbuffer und Colorbuffer Löschen. &lt;br /&gt;
* Helligkeitsmap in den Colorbuffer kopieren.&lt;br /&gt;
* Alle nicht transparanten Objekte in den Zbuffer Rendern. &lt;br /&gt;
* Alle transparenten Poligone mit den gleichen Stencilwerten wie im erstem Pass rendern. Die Bedingung ist, dass nur Polygone in den Zbuffer geschrieben werden, bei den Stencilwerte nicht mit den Stencilbuffer übereinstimmen. Die vordersten Polygone werden so aussortiert und nur die zweite Schicht landet im Zbuffer.&lt;br /&gt;
* Im letztem Rendervorgang müssen die gefilterten Lichtfarben der Transparenten Polygone in den Colorbuffer geschrieben werden. Die Bedingung ist das die Stencilwerte übereinstimmen müssen.&lt;br /&gt;
&lt;br /&gt;
Auch wenn es wie ein großer Mehraufwand aussieht, ist der Anteil der transparenten Poligone doch eher gering. So das deren dreifacher Overdraw kaum eine Rolle spielt. Im Finalem Renderdurch gang gibt es bei den transparenten Polygonen noch eine Besonderheit: Stimmt die Entfernung aus der Shadowmap mit der Entfernung der Lichquellen (fast) überein, so wird das Poligon mit dem Licht aus der Colormap belauchtet. Ist die Entfernung aus der Shadowmap jedoch größer als die entfernung zu lichquellen, enthällt die Colormap die gefilterte Farbe des Lichtes hinter dem Poligon. Für die beleutung des Poligon muss also das Licht der Lichquelle benutzt werden. Sinvoll ist es die helligkeit für diesen Fall im Alphawert der Colormap zu Speichern.&lt;br /&gt;
&lt;br /&gt;
Ansonsten noch ein paar Vorschläge:&lt;br /&gt;
* Objekte die aus dem gleichem Glas sind und auch einfarbig. Sollten mit dem gleichem Stencilwert verarbeitet werden. So sieht z.B. das gefärbte Licht einer zweifach durchstrahlten leicht gefäbten Glasskuppel natürlicher aus als ein Vollschatten. Auch wenn das Licht korrekter weise zwei mal hätte gefiltert werden müssen. &lt;br /&gt;
* Eventuel macht es sind mehrfarbige Objekte in mehrfache einfarbige Objekte zu zerlegen.&lt;br /&gt;
* Komplexe Mehrfachfilterungen sollten vermieden werden oder so gewählt werden, das sie natürlich ausehen. Gute Filter wären komplementärfarben, da dort ein echter Schatten erzeugt wird. Schlechte Kombinationen wären unter anderem Rot+Gelb, Blau+Gelb, usw...&lt;br /&gt;
* Um von den Farbfehlern abzulenken, farbige Objekte in einer rotverschobenen Farbe flourezieren lassen. (Violet-&amp;gt; Blau -&amp;gt; Grün -&amp;gt; Gleb -&amp;gt; Organge -&amp;gt; Rot) Durch blau gefärbte Fenster, blau gefilterte Licht welches Dinge grün aufleuchten lässt nimmt einem jeder PC Modder ab...&lt;br /&gt;
&lt;br /&gt;
===Schattenmap durch eine Heightmap modifizieren===&lt;br /&gt;
Auch wennich hierzu noch kein Beispiel haben, ist es möglich gl_FragDepth mit hilfe einer Heightmap zu modifizieren. Prinzipiell entspricht dies einem einfachem Offsetmapping. Damit wäre durchaus eine Selbstschattierung von Bumpmaps möglich.&lt;br /&gt;
&lt;br /&gt;
===Zweite parabolische Map vermeiden===&lt;br /&gt;
Lichtquellen, die nur in eine Richtung Licht werfen können, wie z.B. Spotlichter oder Lichter, die in Bodenähe oder Wandnähe befestigt sind, benötigen keinen vollständig erfassten Tiefenraum. Die Parabolische Map kann problemlos herein oder herausskaliert werden, so das Öffnungswinkel von 0 bis ca 240 Grad möglich sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das verkleinern des Öffnungswinkels für zusätzliche Spotlichter ermöglicht auch kleinere Tiefenmaps, die in die 9 Zwischenräume der großen gepackt werden können. Die Zwischenräume können noch Maps mit einem Durchmesser von 40% der großen Maps aufnehmen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Texturelookups vermeiden===&lt;br /&gt;
Wenn das Skalarprodukt von normalvec und -lightdir negativ ist, dann ist die Oberfläche von der Lichtquelle abgewandt und Berechnungen für die Lichquelle können komplett übersprungen werden. Diverse Multiplikationen und vorallem Texturelookups können so übersprungen werden. Besondere aufwendige Algorithmen wie selbstschattierende Bumpmaps, können so deutlich Beschleunigt werden. &lt;br /&gt;
&lt;br /&gt;
Für die Beleuchtung sollte dann allerdings auch folgende Zeile verwendet werden. (Das Skalarprodukt von vor der if Abfrage aber umbedingt wiederverwerten!) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
  light += gl_LightSource[0].diffuse * max(dot(normalvec, -lightdir), 0.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Reichweite der Lichtquellen=== &lt;br /&gt;
Leider bietet OpenGL nicht direkt die Möglichkeit die maximale Reichweite einer Lichquelle anzugeben. In den Shadern wird zur Zeit der Wert 15.0 als maximale Entfernung zur Lichtquelle verwendet. Für ein einfaches Programm ist es sicher ausreichend, ansonsten macht es Sinn diesen Wert durch eine Unformvariable zu ersetzten, oder um mehr Flexibiltät zu bekommen durch ein Array aus 8 Uniformfloats.&lt;br /&gt;
&lt;br /&gt;
===Oversampling der Schattenmap===&lt;br /&gt;
Die Qualität lässt sich dadurch mehrere Samples auf der Schattenmap verbessern. Das folgende Codefragment nimmt 3 statt des einem Samples und glättet die Ränder des Schattens. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;const float pof =1.0 /4096.0 *0.7;&lt;br /&gt;
vec4 shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol +vec2(pof,0)).r );&lt;br /&gt;
shadow += step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol+vec2(-pof/2.0,-pof/1.2) ).r );&lt;br /&gt;
shadow += step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol+vec2(-pof/2.0,pof/1.2)).r );&lt;br /&gt;
light += shadow * 0.33 * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&amp;lt;/source&amp;gt;&lt;br /&gt;
Durch 9x Oversampling lässt sich schon eine sehr gute Qualität ereichen, sorgt aber bei 8 Lichtquellen durch die 72 Texturelookups für einen Zusammenbruch der Framerate.&lt;br /&gt;
Wichtig ist auch, dass man beachtet, dass die dualparaboliden Maps an Ihren Ränden undefiniert sind und so zu Artefakten kommen kann wenn man außerhalb des gültigem Bereichs sampled. Eine Möglichkeit wäre einen Bereich zu erfassen, der etwas größer als 180 Grad ist, um am Rand zusätzliche Texel zu schaffen.&lt;br /&gt;
&lt;br /&gt;
===Ein zusätzlicher Renderpass===&lt;br /&gt;
Nach dem die Tiefenmap gerendert würde, wäre es möglich in einem weiterem Framebufferobjekt eine zusätzliche Map zu rendern, in der mit Hilfe einer Kantenerkennung die Helligkeit der Softshadows vorberechnet wird. Auch hier muss berücksichtigt werden, dass die dualparaboliden Maps einen Übergang haben.&lt;br /&gt;
&lt;br /&gt;
===Dynamische Lichter in statische Lightmaps Rendern===&lt;br /&gt;
Wenn sich Lichtquellen nicht relativ zur Umgebung nicht bewegen, ist es möglich sie in eine Lightmap zu rendern. Unter der Annahme, dass Lightmapkoordinaten vorhanden sind (ohne geht es echt nicht gut), müssen diese nur per Vertexshader an den Pixelshader weitergegeben werden. Im Pixelshader kann dann wie im final.frag die Helligkeit berechnet werden und in der Lightmap abgespeichert werden.&lt;br /&gt;
Es ist immer noch möglich, das dynamische Objekte einen Schatten werfen: Es werden nur noch die beweglichen Objekte in die Tiefenmap gerendert. Im Schatten wird dann einfach das Licht der im Schatten liegenden Lichtquelle subtraiert.&lt;br /&gt;
&lt;br /&gt;
===Statische Anteile in den Schattenmaps===&lt;br /&gt;
Es ist möglich mit einer zusätzlichen Matrix die Tiefenmaps zu den Weltkoordinaten auszurichten. Statische Anteile können dann aus einer zweiten Tiefenmap kopiert werden. Ein wenig problematisch ist das Entfernen der Rotation aus der gl_ModelViewMatrix. Das größte Problem ist, das die Positionen der Lichquellen bereits mit der gl_ModelViewMatrix multipliziert sind. Die einfachste Lösung ist, aus den den Rotationswinkeln eine neue Matrix zu erechnen, mit dessen Hilfe die Schattenvektoren für die Texturkoordinatenberechnung zurückgedreht werden. Diese Matrix sollte dann als Uniformvariable übergeben werden.&lt;br /&gt;
Wenn die Schatten durch einen zusätzlichen Renderdurchgang gefiltert werden. Ist es sinvoll die Maps erst hier zu vereinen. Von beiden Tiefenmaps muss nur immer der kleinere Wert genommen werden.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=GLSL_Licht_und_Schatten&amp;diff=24695</id>
		<title>GLSL Licht und Schatten</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=GLSL_Licht_und_Schatten&amp;diff=24695"/>
				<updated>2010-02-10T12:37:28Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Framebufferobjekte */  Kleine Codekorrekturen für Passcalquellcode. NULL gibts bei uns nicht, nur NIL, ungetestet entfernt, Kommentar angepasst&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Offline}}&lt;br /&gt;
&lt;br /&gt;
==Vorwort==&lt;br /&gt;
&lt;br /&gt;
Willkommen zu meinem erstem Tutorial. Schatten können sowohl Traum als auch Albtraum eines jeden OpenGL-Progrmamieres werden. Im Gegensatz zur einfachen Beleuchtung mit Lichtquellen, steigt der Rechenaufwand hier extrem an und ohne Optimierung zwingen die Schatten selbst die modernste Hardware in die Knie.&lt;br /&gt;
Für Schatten gibt es zwei praktikable Algoritmen: Den Stencilschatten und den projezierten Schatten. Hier möchte ich mich auf den projezierten Schatten beschränken, er bietet gegenüber dem Stencilschatten einige Vorteile:&lt;br /&gt;
&lt;br /&gt;
*Die komplette Berechnung kann von der Grakfikkarte übernommen werden&lt;br /&gt;
*Es ist möglich Softshadows zu realisieren&lt;br /&gt;
*Die Shadowmaps können unter Umständen für mehr als ein Frame verwendet werden&lt;br /&gt;
&lt;br /&gt;
Um den Rechenaufwand zu veringern werde ich hier zusätzliche Projektionstechniken zeigen, die über den Vertexshader realisiert werden: Die perspektivische Map und das parabolide Mapping. &lt;br /&gt;
&lt;br /&gt;
Für sehr weit entfernte Lichtquellen und offene Szenen ist der Einsatz von perspektisch angepassten Maps sinvoll. Da das Licht quasi parallel ausgestrahlt wird. Ist ein winkelabhängiger Cube oder dualparabolische Map kaum möglich. Auch eine einfache quadratische Shadowmap zeigt deutliche Schwächen bei der Auflösung im Nahbereich und dem zu hohem Oversampling in der Entfernung.&lt;br /&gt;
&lt;br /&gt;
Das parabolide Mapping ermöglicht nicht nur die Simulation eine Fischaugenoptik, sondern kann auch die Cubemap vollständig ersetzen. Durch einen geringfügig höheren Rechen- und Programieraufwand genügen zwei Renderpasses um eine vollständige Tiefen- oder Reflektionsmap zu erstellen. Was gegenüber der klassischen Cubemap den Prozessor und GPU um den Faktor 3 entlastet.&lt;br /&gt;
&lt;br /&gt;
==Vorkenntnisse==&lt;br /&gt;
Dieses Tutorial basiert auf den grundlegenden Techniken, die erst in den letzten Jahren entwickelt wurden. Jeder der hier mit anfängt, sollte die zwei anderenen GLSL Tutorials gelesen haben und einfache Fragmentshader schreiben können. Auch das Laden und Einbinden von Texturen in die Shader sollte kein Problem mehr darstellen.&lt;br /&gt;
&lt;br /&gt;
===Framebufferobjekte===&lt;br /&gt;
Für das Erstellen von dual paraboliden Tiefentexturen ist noch das Rendern in Framebufferobjekten Vorraussetzung (zu denen es leider noch kein Tutorial gibt). Damit der Einstieg nicht zu schwer wird sollte dieser Code helfen das FBO zu initialsisieren:&lt;br /&gt;
&lt;br /&gt;
Als Erstes müssen die nötigen Extensions initialisiert werden&lt;br /&gt;
Dann sollten die benötigten Modelle als VBO in die Grafikkarte hochgeladen werden.&lt;br /&gt;
Nun muss das Framebufferobjekt (FBO) für die Schattenmaps erzeugt werdern.&lt;br /&gt;
So könnte die Initialsierung des FBOs aussehen. C code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;GLuint shadow_map = 0; // &lt;br /&gt;
GLuint shadow_fbo = 0; // the shadow texture&lt;br /&gt;
GLuint shadow_size = 4096; //muss kleiner/gleich maximaler 2D-Texturgröße sein&lt;br /&gt;
&lt;br /&gt;
glGenTextures (1, &amp;amp;shadow_map); //In Pascal das &amp;amp; durch ein @ ersetzten&lt;br /&gt;
glBindTexture (GL_TEXTURE_2D, shadow_map);&lt;br /&gt;
glTexImage2D (GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, shadow_size, shadow_size, 0,GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE, NULL);&lt;br /&gt;
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
&lt;br /&gt;
glGenFramebuffersEXT (1, &amp;amp;shadow_fbo); //In Pascal das &amp;amp; durch ein @ ersetzten&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fbo);&lt;br /&gt;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,shadow_map, 0);&lt;br /&gt;
glDrawBuffer (GL_FALSE);&lt;br /&gt;
glReadBuffer (GL_FALSE);&lt;br /&gt;
GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); //noch ein wenig Code anfügen um den Status zu überprüfen.&amp;lt;/source&amp;gt;&lt;br /&gt;
Pascal :&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var &lt;br /&gt;
  shadow_map,&lt;br /&gt;
  shadow_fbo,&lt;br /&gt;
  shadow_size : TGLuint;&lt;br /&gt;
  status      : TGLenum; &lt;br /&gt;
begin&lt;br /&gt;
  shadow_size := 4096; // muss kleiner/gleich maximaler 2D-Texturgröße sein&lt;br /&gt;
&lt;br /&gt;
  glGenTextures(1, @shadow_map);&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, shadow_map);&lt;br /&gt;
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadow_size, shadow_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NIL);&lt;br /&gt;
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);&lt;br /&gt;
&lt;br /&gt;
  glGenFramebuffersEXT(1, @shadow_fbo);&lt;br /&gt;
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo);&lt;br /&gt;
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, shadow_map, 0);&lt;br /&gt;
  glDrawBuffer (GL_FALSE);&lt;br /&gt;
  glReadBuffer(GL_FALSE);&lt;br /&gt;
  Status := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); //noch ein wenig Code anfügen um den Status zu überprüfen.&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
Jetzt sollten die Shader und weiter Texturen geladen werden.&lt;br /&gt;
&lt;br /&gt;
===Beschleunigtes Rendern===&lt;br /&gt;
&lt;br /&gt;
Ich empfehle auch die zu rendernden Daten als Vertexbufferobjekte zu übergeben, da sonst die Mehrfachverwendung der Daten zu einer extremen Bremse wird. Da es hierzu bereits ein Tutorial gibt werde ich hier nichts mehr darüber schrieben.&lt;br /&gt;
Alternativ sollte alles was zwischen glBegin und glEnd in Displaylisten gespeichter werden. Das Speichern von Texturwechseln usw ist nicht sinvoll, da diese nicht zum Rendern der Shadowmaps benötig werden.&lt;br /&gt;
&lt;br /&gt;
Bei mehrfachen Lichquellen kann es wiederum Sinn machen den ersten Rendervorgang inclusive Shaderwechsel in einer Displayliste zwischenzuspeichen und die zusätzlichen Schadowmaps mit dieser zu rendern.&lt;br /&gt;
&lt;br /&gt;
===Algemeines zu GLSL===&lt;br /&gt;
Ich möchte nocheinmal darauf hinweisen, das sich uniformvariablen nur setzten Lassen, wenn der entsprechnde shader gebunden ist. (Es funktionier nicht wenn der shader nicht gebunden ist. Warum man den shader dabei allerdings angeben muss ist mir nicht so ganz klar)&lt;br /&gt;
In den Beispielen werden nur die Uniformvariablen wärend des Rendervorgangs neu gesetzt die sich ändern.  Die zuweisung der TMU zu einem Sampler gehöhrt in der Regel nicht dazu. &lt;br /&gt;
&lt;br /&gt;
===Grundlegendes zu den Koordinatensystemen in den Shadern===&lt;br /&gt;
&lt;br /&gt;
Im Vertexshader müssen alle komponenten von gl_Position in einem Bereich von -1.0 bis 1.0 gebracht werden. Besonders beim Z-Wert könnte es verwirrend, dass der Bereich  von gl_FragDepth im Fragmentshader von 0.0 bis 1.0 geht. Auch muss beachtet werden, dass Texturkordinaten den bereich von 0.0 bis 1.0 nutzen, wärend die Rendertargets im Bereich on -1.0 bis 1.0 arbeiten.&lt;br /&gt;
In den Shadern werden daher öfters Multimplikationen mit 0.5 und einer anschließenden Addition von 0.5 auftreten.&lt;br /&gt;
&lt;br /&gt;
==Perspektivische Maps==&lt;br /&gt;
&lt;br /&gt;
In dem erstem Teil dieses Artikels geht es um perspektivisch angepasste Schattenmaps. Normale projezierte Schatten haben das Problem, das sie im Nahenbereich besonders stark verpixeln und in der Entfernung durch ein viel zu hohes Oversampling Bandbreite verschwenden.&lt;br /&gt;
&lt;br /&gt;
Für eine globale Lichquelle wird nur ein Vektor gegeben, der die Richtung des Lichtes beschreibt. Die gedachte Lichtquelle ist quasi unendlich weit weg. Da eine Entfernungsberechnung zur Lichquelle unmöglich ist, muss die Schattenberechnung relativ zu einer Referenzebene durchgeführt werden. Diese Ebene kann sowohl Senkrecht zum Lichvektor, als auch parallel zum gedachtem Boden ausgerichtet werden. Die Ausrichtung der Referenzebene beeinflusst die später sichtbare Auflösung der Schatten.&lt;br /&gt;
&lt;br /&gt;
Nach dem ein Vertex auf die Ebene projeziert wurde und der Abstand ein einen berech von 0.0...1.0 gebracht wurde, muss diese unendlich große Ebene noch auf eine endliche Größe projeziert werden, die auf eine Textur passt und die entfernungsabhängige Detailierung beachtet.&lt;br /&gt;
&lt;br /&gt;
Wenn wir unsere Referenzebene einfachhalber den Horizont schneidet (und auch den Bildschirm in obere und untere Hälfte teilt) Könnte ein Algorimus in etwa so aussehen (Dieser lässt sich später in ein Vertexshaderprogramm umsetzten):&lt;br /&gt;
&lt;br /&gt;
Projeziere den Vertex in die Modelview (Diese Schritt wurde auch bei den dualparaboliden Maps durchgeführt)&lt;br /&gt;
Ermittel den Schnittpunt des vom Vertex ausgehendem gedachtem Lichtstrahl und der Referenzebene.&lt;br /&gt;
Benutze den Abstand zwischen Schnittpunkt und Vertex um den Z-Wert zu ermitteln. (Es sind zwei zusätzlich referenzwerte nötig die die funktion Farclip und Nearclip übernehmen)&lt;br /&gt;
Projeziere die Ebene auf eine Ebene die in eine Textur passt pos/=abs(pos)+1.0 passt recht gut.&lt;br /&gt;
Anschließend wird noch die Schadowmap noch gestreckt und der Bereich hinter der Kammera entfernt.&lt;br /&gt;
&lt;br /&gt;
Das wichtigste ist, dass beim auswerten der shadowmaps der gleiche Projektionsalgoritmus verwendet wird wie beim generieren.&lt;br /&gt;
&lt;br /&gt;
Prinzipell sollte sich der Algoritmus schon auf einer Geforce 3 oder Radeon 8500 implementieren lassen. Da da der Code hier in GLSL geschrieben ist, sollte in etwa Shadermodel 2.0 unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
Geschwindigkeitsmäßig ist dieser Algoritmus den Stencilshadows deutlich überlegen. Auch bei Stencilshadows sind mehrere Renderpasses nötig. Vorallem das extruieren der Siluetten kostet einiges an Bandbreite. Der geschätzte Aufwand ist etwa 20 (Aufwendige Shader im Finalem Renderdurchgang)bis 80% (CPU limitiert Geometrieübergabe) Mehraufwand gegenüber einer Schattenlos gerenderten Scene.&lt;br /&gt;
Auch die Qualität ist nicht schlechter. Bei der Verwendung von weichen Schatten wirken Shadowmaps natürlicher als die extrem scharfen Stencilshadows. &lt;br /&gt;
&lt;br /&gt;
===Hauptprogramm===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife könnte folgender Code verwendet werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
	glBindTexture(GL_TEXTURE_2D, 0 ); //Entfernt alle Texturen aus der ersten TMU&lt;br /&gt;
	glUseProgramObjectARB(shadow); //lädt den Schattenshader&lt;br /&gt;
	glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fb); //Bindet das Framebufferobjekt&lt;br /&gt;
	&lt;br /&gt;
	glViewport (0, 0,shadow_sz,shadow_sz); //Anpassen des Viewportes &lt;br /&gt;
	glClear(GL_DEPTH_BUFFER_BIT); //Z-Buffer löschen&lt;br /&gt;
	&lt;br /&gt;
	render(); //Erster Renderdurchgang&lt;br /&gt;
&lt;br /&gt;
	glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); //Normalen Framebuffer binden&lt;br /&gt;
	glBindTexture(GL_TEXTURE_2D, shadow_tx ); //Tiefenmap an die erste TMU binden&lt;br /&gt;
	glUseProgramObjectARB(final); //finalen shader binden&lt;br /&gt;
	&lt;br /&gt;
	glViewport(0, 0, screen_size_x, screen_size_y);&lt;br /&gt;
	&lt;br /&gt;
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Color und Z-Buffer löschen&lt;br /&gt;
	render(); //rendern&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Shader===&lt;br /&gt;
&lt;br /&gt;
Als erstes der Vertexshader zum generieren der Schadowmap. shadow.vert:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void){&lt;br /&gt;
&lt;br /&gt;
	vec3 lightdir = gl_NormalMatrix * normalize(vec3(0.1,-1.0,0.0)); //Lichtvektor in den Modelsprace rotieren&lt;br /&gt;
	vec3 mvertex =  vec3 (gl_ModelViewMatrix * gl_Vertex); //Vertex in den Modelspace projezieren&lt;br /&gt;
	vec2 pos = mvertex.xz + lightdir.xz * -mvertex.y/lightdir.y; //Schnittpunkt mit der XZ Referenzebene&lt;br /&gt;
	pos = pos / (abs(pos)+1.0); //Projektion der Ebene auf ein Quadrat&lt;br /&gt;
	pos = pos * vec2(1.0,1.8) + vec2(0.0,0.8); //Abschneiden des Bereiches hinter der Kammera&lt;br /&gt;
	gl_Position.xy = pos;&lt;br /&gt;
	gl_Position.z = -mvertex.y ; // Der Bereich von +-1 über der Referenzebene wird erfasst&lt;br /&gt;
	gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
 	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Lichtrichtung wird vorläufig noch fest übergeben. Eine Auswertung einer Opengl Lichtquelle oder einer Uniformvariable wäre ebenfalls möglich. Anschließend wird der Vertex in die Modelview projeziert und der Schnittpunkt des vom Vertexausgehendem Lichstrahls mit der Referenszebene berechnet. Als letztes wird noch der Abstand zur Referenzebenein einem Bereich 0..1  umgerechnet und die Texturkoordinaten für eventuelles Alphamasking oder Heightmapping durchgeschleift. Soll Alphamasking verwendet werden, muss ein entsprechender Shader geschrieben werden der bei den freizulassenden pixeln discard(); aufruft. Dies sollte jedoch nur für die betroffenen Poligone stat finden, da die Grafikkarte dann keine Early-Z Optimierungen verwenden kann. Ansonsten ist der Fragmentshader ist sehr einfach: shadow.frag:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
void main(void){}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die für die Auswertung müssen wir im finalem Renderdurchgang exakt die gleichen Texturkoordinaten für die Shadowmap generieren. Allerdings gibt es eine Besonderheit: Die koordinaten einer Textur reichen von 0;0 bis 1;1, Die Koordinaten eines Rendertargets reichen jedoch von -1;-1 bis 1;1, so das eine zusätzliche korrektor nötig ist.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 spos;&lt;br /&gt;
&lt;br /&gt;
void main(void){&lt;br /&gt;
        vec3 lightdir = gl_NormalMatrix * normalize(vec3(0.1,-1.0,0.0));&lt;br /&gt;
        vec3 mvertex =  vec3 (gl_ModelViewMatrix * gl_Vertex);&lt;br /&gt;
        vec2 pos = mvertex.xz + lightdir.xz * -mvertex.y/lightdir.y;&lt;br /&gt;
        pos = pos / (abs(pos)+1.0);&lt;br /&gt;
        pos = pos * vec2(1.0,1.8) + vec2(0.0,0.8); //Abschneiden des Bereiches hinter der Kammera&lt;br /&gt;
        pos = pos * 0.5 + 0.5; //auf Texturkoordinaten umrechnen&lt;br /&gt;
 &lt;br /&gt;
        spos.xy = pos; //Daten in einer Varying verpacken&lt;br /&gt;
        spos.z = -mvertex.y * 0.5 + 0.5 - 0.005; // far and near clamping and Anti-Z-fighting-offset &lt;br /&gt;
 	&lt;br /&gt;
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; //Die echte Transformation&lt;br /&gt;
 &lt;br /&gt;
        gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
        gl_TexCoord[1] = gl_MultiTexCoord1;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ersten 5 Zeilen der main() sollten exakt das gleiche tun wie der Vertexshader zum gnerieren der Map.&lt;br /&gt;
&lt;br /&gt;
Nun fehlt noch ein Fragmentshader für den letzten Durchgang:&lt;br /&gt;
&lt;br /&gt;
Es muss noch der Noralvektor berücksichtigt werden!!!&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Shadowmap;&lt;br /&gt;
varying vec3 spos;&lt;br /&gt;
 &lt;br /&gt;
void main(void){&lt;br /&gt;
        if (texture2D(Shadowmap, spos.xy).r &amp;gt; spos.z ){&lt;br /&gt;
              //Licht&lt;br /&gt;
              gl_FragColor = vec4(1.0,1.0,1.0,1.0);&lt;br /&gt;
              }&lt;br /&gt;
        else{&lt;br /&gt;
              //Schatten&lt;br /&gt;
              gl_FragColor = vec4(0.5,0.5,0.5,1.0);&lt;br /&gt;
              }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parabolide Maps==&lt;br /&gt;
&lt;br /&gt;
Einfache parabolide Maps können für alle Punktlichquellen verwendet werden, deren Licht nicht in alle Richtungen abgestrahlt wird. Darunter fallen vorallem Spots und an Wänden oder Decken befestigte Lampen. Im gegensatz zur Paralelem Licht oder einer Punktlichquelle bringt eine solche Lichtquelle häufig eine Helligkeitsmap mit. Für die Helligkeitsmap und die Schattenmap können die gleichen Texturkoordinaten verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Bei kleinen Öffnungswinkeln hat die parabolide Map keinen Vorteil gegenüber einer normalen Projektion. Der Vortiel ist jedoch das der Code sich für Öffnungswinkel von bis zu ~240 Grad eignet. &lt;br /&gt;
&lt;br /&gt;
Um eine solche Lichquelle zu beschreiben weden nicht weniger als drei Vektoren benötigt:&lt;br /&gt;
&lt;br /&gt;
* Position&lt;br /&gt;
* Richtung &lt;br /&gt;
* Tangent&lt;br /&gt;
&lt;br /&gt;
Wärend die Funktion der ersten beiden Vektoren klar ist, wird der Tangent wird dazu benötigt die Schattenmap und Helligkeitsmap auszurichten. Er ist Senkrecht zur Richtung tangential zur Textur ausgerichtet &lt;br /&gt;
Beschreiben lässt sich diese Funktion lässte sich am ehesten durch das Verdrehen einer Taschenlampe. Wenn die Schattenmap gegenüber den schattenwerfenden Objekten verdreht wird, sieht das Bild auf keinen Fall mehr natürlich aus.&lt;br /&gt;
 &lt;br /&gt;
Es ist sowohl möglich die Berechnungen im Vertexshader durchzuführen, als auch eine entsprechnede Matrix in den Uniformvariablen abzulegen. Wenn die Berechnungen per Matrix durchgefühert werden lässt sich das Prinzip der paraboliden Maps zuindest als Reflektionsmap nutzen. Ein weiterer Vorteil an einer vorberechneten Matrix ist, dass diese auch für shadowmap verwendet werdne kann die nicht jedes Frame neu berechnet werden.&lt;br /&gt;
&lt;br /&gt;
==Dual Parabolide Maps==&lt;br /&gt;
Von OpenGL kennen wir zwei Projektionsmöglichkeiten: Orthografische und perspektivische Projektion. Beide Projektionen arbeiten ohne Verzerrung. Jede Gerade bleibt beim Transformieren eine Gerade. Wenn man dagegen das Bild eines Fischeyeobjektives betrachtet, allen einem sofort die zu Kurven verzerrten Geraden auf. Der entscheidene Vorteil an einer Fisheyeaufnahme ist, dass ein Öffnungswinkel von 180 Grad erfasst werden kann. Zwei entgegensetzte Aufnahmen können so problemlos den kompletten Raum um die Kamera erfassen.&lt;br /&gt;
&lt;br /&gt;
Für das Erstellen der Tiefenmap ist es notwendig den Raum um das reflektierende Objekt in eine Textur zu rendern. Meistens wird hier eine Cubemap verwendet. Soll diese dynamisch generiert werden, ist es auffällig, dass die Scene ganze 6 mal gerendert werden muss. Mit der dual paraboliden Map sind nur noch zwei Rendervorgänge nötig, es wird zwar keine Füllrate eingespart, dafür müssen nun nur noch 1/3 der Daten transformiert werden, so das die Vertexshader und die CPU entlastet werden.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Optimierung ist unter Umständen möglich: Wenn bei einer Cubemap auf eine der Flächen verzichte werden kann. Z.B. wird die Reflektion im Lack eines Autos so gut wie nie verdeckte Straße zeigen. Auch ist für eine an einer  Wand befestigten Lampe nur eine halbkugelförmige Shadowmap nötig. Wenn sie einen Abstand zur Wand hat, genügt es auch hier den Blickwinkel von 180 Grad etwas zu erweitern.&lt;br /&gt;
&lt;br /&gt;
Die Projektion der dualparaboliden Map kann man sich am besten Bild eines Fisheyobjektives vorstellen. Mathematisch etwas genauer ist das Reflektionsbild der umgebenden Welt in einem Rotationsparaboliden.&lt;br /&gt;
&lt;br /&gt;
Die Hardwareanforderungen an den Pixelshader sind nicht gerade gering. Der Pixelshader für die 8fachen Lichquellen kommt nach dem Compelieren auf über 170 Instruktions. Eine Shader 2.0 Karte wie z.B. die Radeon 9x00 sind hier hoffnungslos überfordert da sie nur an 3 Stellen im Programm auf die Textureinheiten zugreifen können und der Assembler nicht mehr in der Lage ist die Instruktions passend umzusortieren. Noch fataler wird es  wenn die Texturelookups durch dynamisches Branching übersprungen weder sollen: Die Karte hat keine Chance mehr diese umzusortieren.&lt;br /&gt;
&lt;br /&gt;
Wer dualparbolide Maps auf SM2.0 Karten einsetzten will sollte damit rechnen, dass das Limit bei 2 bis 4 Maps liegen sollte.&lt;br /&gt;
&lt;br /&gt;
===Hauptprogramm===&lt;br /&gt;
&lt;br /&gt;
So kann in der Hauptschleife das rendern der 16 paraboliden Maps und der anschließende Finale Renderdurchgang durchgeführt werden:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;//Shader für Dualparabolische Mpas aktivieren&lt;br /&gt;
glUseProgramObjectARB(parabol);&lt;br /&gt;
&lt;br /&gt;
//Framebufferobjekt aktivieren&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, shadow_fb);&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
//Die 8 Lichtquellen Rendern&lt;br /&gt;
for (int light;light&amp;lt;8;light++){&lt;br /&gt;
        glViewport (shadow_size/2*(lights/4),shadow_size/4 *(light%4),shadow_size/4,shadow_size/4);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;light&amp;quot;),light);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;renderpass&amp;quot;),0);&lt;br /&gt;
        render();&lt;br /&gt;
        glViewport (shadow_size/4+shadow_size/2*(lights/4), shadow_size/4*(light%4),shadow_size/4 ,shadow_size/4);&lt;br /&gt;
        glUniform1iARB(glGetUniformLocationARB(parabol, &amp;quot;renderpass&amp;quot;),1);&lt;br /&gt;
        render();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
// Framebufferobjekt deaktivieren&lt;br /&gt;
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
&lt;br /&gt;
//Richtigen Shader aktivieren&lt;br /&gt;
glUseProgramObjectARB(final);&lt;br /&gt;
//Vieport an Fenstergröße anpassen&lt;br /&gt;
glViewport(0, 0,Windowsize_X,Windowsize_Y);&lt;br /&gt;
&lt;br /&gt;
//Frame rendern&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
render();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ungetesteter Pascalcode:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
//Shader für Dualparabolische Mpas aktivieren&lt;br /&gt;
glUseProgramObjectARB(parabol);&lt;br /&gt;
&lt;br /&gt;
//Framebufferobjekt aktivieren&lt;br /&gt;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fb);&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
//Die 8 Lichtquellen Rendern&lt;br /&gt;
for light := 0 to 7 do&lt;br /&gt;
begin&lt;br /&gt;
  glViewport(shadow_size/2*(lights/4), shadow_size/4 *(light mod 4), shadow_size/4, shadow_size/4);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'light'), light);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'renderpass'), 0);&lt;br /&gt;
  render();&lt;br /&gt;
  glViewport(shadow_size/4+shadow_size/2*(lights/4), shadow_size/4*(light mod 4), shadow_size/4, shadow_size/4);&lt;br /&gt;
  glUniform1iARB(glGetUniformLocationARB(parabol, 'renderpass'),1);&lt;br /&gt;
  render();&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// Framebufferobjekt deaktivieren&lt;br /&gt;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);&lt;br /&gt;
&lt;br /&gt;
//Richtigen Shader aktivieren&lt;br /&gt;
glUseProgramObjectARB(final);&lt;br /&gt;
//Viewport an Fenstergröße anpassen&lt;br /&gt;
glViewport(0, 0, Windowsize_X, Windowsize_Y);&lt;br /&gt;
&lt;br /&gt;
//Frame rendern&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
render();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Die Shader===&lt;br /&gt;
&lt;br /&gt;
====Shader zum Rendern der Schattenmaps====&lt;br /&gt;
parabol.vert&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;  uniform int renderpass;&lt;br /&gt;
  uniform int light;&lt;br /&gt;
  varying vec3 normal;&lt;br /&gt;
  varying vec3 pos;&lt;br /&gt;
&lt;br /&gt;
  void main(void){&lt;br /&gt;
&lt;br /&gt;
	gl_Position = gl_ModelViewMatrix * gl_Vertex - gl_LightSource[light].position ;&lt;br /&gt;
&lt;br /&gt;
	float L= length (gl_Position.xyz);&lt;br /&gt;
	gl_Position /= -L;&lt;br /&gt;
	if (renderpass == 1) gl_Position.z *=-1.0;&lt;br /&gt;
	gl_Position.z += 1.0;&lt;br /&gt;
	gl_Position.xy /= gl_Position.z;&lt;br /&gt;
	if (gl_Position.z &amp;gt;= 0.01){&lt;br /&gt;
		gl_Position.z = L / 15.0;//Todo: optimieren&lt;br /&gt;
		gl_Position.w = 1.0;&lt;br /&gt;
		}&lt;br /&gt;
	else{&lt;br /&gt;
		gl_Position.z = -1.0;&lt;br /&gt;
		gl_Position.w = -1.0;&lt;br /&gt;
		}&lt;br /&gt;
        &lt;br /&gt;
        gl_Position.z = 2.0 * gl_Position.z -1.0; //Todo: optimieren&lt;br /&gt;
	pos=gl_Position.xyz;&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
parabol.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 pos;&lt;br /&gt;
void main(void){&lt;br /&gt;
	if (length(pos.xy)&amp;gt;1.005)discard; //Diese Zeile kann durchaus entfallen. Kosten/Nutzen unbekannt.&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Uniformaviablen, die gesetzt werden müssen: Eine ist die Nummer der aktuellen Lichtquelle und die zweite der Renderpass, der angibt ob die Vorder- oder Rückseite der parabolischen Map gerendert werden soll. Eine automatische Berechnung der Texturkoordinaten wäre zwar möglich, jedoch ist die Änderung des Viewports deutlich weniger Rechenaufwendig.&lt;br /&gt;
&lt;br /&gt;
Statt einer Multiplikation des gl_Vertex mit der gl_ModelViewProjektionMatrix wird hier nur mit der gl_ModelViewMatrix multipliziert. Dadurch werden nur die Transformationen durchgeführt und die Projektion übersprungen.&lt;br /&gt;
Die Division durch -L entspricht weitgehend einer Normalsierung, spiegelt die Welt jedoch in die richtige Lage. L enthält jetzt die Tiefeninformation, gl_Position einen Vektor, der von der Kammera auf den Vertex zeigt. Mit den zwei folgenden Zeilen wird der Vektor parabolisch auf die Bildschirmkoordinaten projeziert (Intervall von -1.0 bis 1.0). Mit Hilfe der folgenden if-Abfrage werden alle Vertices hinter der Kammera geclipt. Nur sichtbare Vertices bekommen gültige z Werte für den Zbuffer im Intervall von -1.0 bis 1.0. &lt;br /&gt;
&lt;br /&gt;
Der Fragmentshader ist extrem einfach, da wir aufgrund des nicht vorhandem Colorbuffers keinen Farbwert benötigen lassen wir diesen wie bei den perspektivischen Maps einfach undefiniert.&lt;br /&gt;
Zudem verlassen wir den Shader mit discard, wenn der der Pixel außerhalb der aktuellen paraboliden Map liegt. Die Voteil ist, das nur der kreisförmige Bereich der Map verwendet wird, der Nachteil, das durchaus eine Early-Z optimierung nicht mehr möglich ist. Sehr Sinvoll sollte dies sein, wenn die Shadowmaps dynamisch nach benötigter Größe angeordnet werden. Da sich Kreise besser als Quadrate packen lassen.&lt;br /&gt;
&lt;br /&gt;
====Shader für den finalen Renderdurchgang====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
final.vert&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
&lt;br /&gt;
void main(void){&lt;br /&gt;
	Normal = gl_NormalMatrix * gl_Normal;&lt;br /&gt;
 	ModelVertex  = vec3 (gl_ModelViewMatrix * gl_Vertex);&lt;br /&gt;
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;&lt;br /&gt;
	gl_TexCoord[0] = gl_MultiTexCoord0;&lt;br /&gt;
 	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
final.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
&lt;br /&gt;
uniform sampler2D Texture0; // Eine normale Textur &lt;br /&gt;
uniform sampler2D Shadowmap;  //Damit ist auch die 4. TMU belegt..&lt;br /&gt;
uniform int MaxLights;&lt;br /&gt;
&lt;br /&gt;
//Achtung folgende Zeile ist nicht GLSL konform. &lt;br /&gt;
//Workaround: Array als Uniform übergeben oder durch sehr aufwendige berechnung erstzten&lt;br /&gt;
//Sollte es auch auf ATI Karten funktinieren, frage ich mich warum es nicht erlaubt ist...&lt;br /&gt;
const vec2 texofset[8] = {vec2 (0.125,0.125), vec2 (0.125,0.375), vec2 (0.125,0.625), vec2 (0.125,0.875),&lt;br /&gt;
			  vec2 (0.625,0.125), vec2 (0.625,0.375), vec2 (0.625,0.625), vec2 (0.625,0.875)};&lt;br /&gt;
void main(void){&lt;br /&gt;
	vec4 light=vec4 (0.2, 0.2, 0.2, 0.0); //Emmitiertes Licht&lt;br /&gt;
	vec3 normalvec =normalize(Normal.xyz);&lt;br /&gt;
	for (int LightNum = 0;LightNum &amp;lt; MaxLights; LightNum++){&lt;br /&gt;
		vec3 lightvec = ModelVertex - gl_LightSource[LightNum].position.xyz;&lt;br /&gt;
		vec3 lightdir = normalize( lightvec );&lt;br /&gt;
		vec2 parabol = texofset[LightNum];&lt;br /&gt;
		if (lightdir.z &amp;gt; 0.0){&lt;br /&gt;
			parabol.t += 0.25;&lt;br /&gt;
			}&lt;br /&gt;
                // parabolische Projektion für subtextur&lt;br /&gt;
		parabol -=  lightdir.xy * 0.125/ (abs (lightdir.z) + 1.0); &lt;br /&gt;
		vec4 shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol).r );&lt;br /&gt;
		light += shadow * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&lt;br /&gt;
		}&lt;br /&gt;
	vec4 color = texture2D(Texture0, vec2(gl_TexCoord[0]));	//Textur auslesen; &lt;br /&gt;
	gl_FragColor = light * color ;&lt;br /&gt;
	}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglicher weise für ATI taugliche Variante:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
varying vec3 Normal;&lt;br /&gt;
varying vec3 ModelVertex;&lt;br /&gt;
 &lt;br /&gt;
uniform sampler2D Texture0; // Eine normale Textur &lt;br /&gt;
uniform sampler2D Shadowmap;  //Damit ist auch die 4. TMU belegt..&lt;br /&gt;
const int MaxLights=8;&lt;br /&gt;
 &lt;br /&gt;
vec2 texofset[8]; &lt;br /&gt;
void main(void){&lt;br /&gt;
	texofset[0] = vec2 (0.125,0.125);&lt;br /&gt;
	texofset[1] = vec2 (0.125,0.375);&lt;br /&gt;
	texofset[2] = vec2 (0.125,0.625);&lt;br /&gt;
	texofset[3] = vec2 (0.125,0.875);&lt;br /&gt;
	texofset[4] = vec2 (0.625,0.125);&lt;br /&gt;
	texofset[5] = vec2 (0.625,0.375);&lt;br /&gt;
	texofset[6] = vec2 (0.625,0.625);&lt;br /&gt;
	texofset[7] = vec2 (0.625,0.875);&lt;br /&gt;
&lt;br /&gt;
        vec4 light=vec4 (0.2, 0.2, 0.2, 0.0); //Emmitiertes Licht&lt;br /&gt;
        vec3 normalvec =normalize(Normal.xyz);&lt;br /&gt;
        for (int LightNum = 0;LightNum &amp;lt; MaxLights; LightNum++){&lt;br /&gt;
                vec3 lightvec = ModelVertex - gl_LightSource[LightNum].position.xyz;&lt;br /&gt;
                vec3 lightdir = normalize( lightvec );&lt;br /&gt;
                vec2 parabol = texofset[LightNum];&lt;br /&gt;
                if (lightdir.z &amp;gt; 0.0){&lt;br /&gt;
                        parabol.t += 0.25;&lt;br /&gt;
                        }&lt;br /&gt;
                // parabolische Projektion für subtextur&lt;br /&gt;
                parabol -=  lightdir.xy * 0.125/ (abs (lightdir.z) + 1.0); &lt;br /&gt;
                float shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol).r );&lt;br /&gt;
                light += shadow * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&lt;br /&gt;
                }&lt;br /&gt;
        vec4 color = texture2D(Texture0, vec2(gl_TexCoord[0])); //Textur auslesen; &lt;br /&gt;
        gl_FragColor = light * color ;&lt;br /&gt;
        }&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Diese Shader besitzen 3 Uniformvariablen, die unbedingt mit den richtigen Werten gefüllt werden müssen. Zwei davon sind Texturen, die dritte die Anzahl der aktiven Lichtquellen. Es ist wichtig zu wissen, dass der Shader nicht den OpenGL-Status der Lichquellen berücksichtigt und nur die Daten der Ersten bis MaxLights holt.&lt;br /&gt;
Während bei den Schattenmaps die meiste Arbeit im Vertexshader erledigt werden könnte, ist dieser sehr Fragmentshader lastig. Die Texturkoordinatenberechnung ist sehr ähnlich zu der im shadow.vert. Die größte Änderung ist, dass hier abhängig von der Lichtquellennummer ein Offset aufaddiert wird um die Untertextur auszuwählen. Ein zusätzlicher Offset wird dazuaddiert, wenn auf die zweite parabolide Map einer Lichtquelle zugegriffen wird.&lt;br /&gt;
Um ein dynamisches Branching zu vermeiden, wird mit der Stepfunktion ermittelt ob sich das Fragment im Schatten befindet.&lt;br /&gt;
&lt;br /&gt;
==Optimierungen und Verbesserungen==&lt;br /&gt;
Hier sind noch einige Vorschläge, die helfen können um besser Qualität oder Leistungen im eigenem Programm zu bekommen. Eine uniververselle Lösung lässt sich nur auf kosten von Performance schreiben. Viel besser ist es, wenn man die Shader an die jeweilige Situation anpasst. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Schatten durch Alphatest===&lt;br /&gt;
Der bisherige Schattenshader kann nur ganze Polygone einen Schatten werfen lassen. Wenn shadow.vert so ergänzt wird, das die Texturkoordinaten in den Fragmentshader  weitergereicht werden, dann ist es mit folgendem Fragmentshader möglich Shatten in Abhängikeit einer Alphatextur zu rendern:&lt;br /&gt;
&lt;br /&gt;
shadow.frag&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
uniform sampler2D Texture0;&lt;br /&gt;
void main(void)&lt;br /&gt;
{&lt;br /&gt;
        if (texture2D(Texture0,vec2(gl_TexCoord[0])).a &amp;lt; 0.5) discard;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Der Shader wird verlassen wenn das Texel einen Alphawert von kleiner als 50% hat. Damit lassen sich Schatten von Pflanzen wesentlich realistischer darstellen. Dieser Shader sollte natürlich nur dann verwendet werden, wenn eine Alphakanal in der Textur vorhanden ist. Auch Shader mit Paralax- oder Displacementmapping arbeiten kann man so um einen Schatten ergänzen, wenn die Polygone transparente Teile enthalten.&lt;br /&gt;
Es ist auch möglich den shader zu verlassen, wenn eine bestimmte Farbe in der Textur gefunden wird, dann nimmt die Alphamaske keinen Speicherplatz mehr weg.&lt;br /&gt;
&lt;br /&gt;
===Farbiges Glas===&lt;br /&gt;
&lt;br /&gt;
Schatten hat jetzt ja sachon fast jeder. Aber wie wäre es mal mit einfärben von dynamischen Lichtquellen?&lt;br /&gt;
Der Algoritmus ist nicht schwer:&lt;br /&gt;
&lt;br /&gt;
* Alle Undurchichtigen Sceneteile in die Tiefenmaps gerendert. &lt;br /&gt;
* Zusätzlich wird eine Colormap gebunden und das Schreiben in den Zbuffer unterbunden.&lt;br /&gt;
* Die Colormap wird mit Weiß oder einer Helligkeitsmap initialisiert.&lt;br /&gt;
* Rendern aller transparenten Objekten&lt;br /&gt;
* Auf finales Rendern umschalten&lt;br /&gt;
* Alle undurchsichtigen Objekte mit hilfe der Schadowmap und der modifizierten Beleuchtungmap beleuchten.&lt;br /&gt;
* Alle Transparenten Objekte rendern, unter Berücksichtigung, dass die Lichtquelle bereits das gefilterte Licht aussendet. Dieses Blending sollte rückgängig gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Bei diesem Algoritmus bleibt noch das Alphablendingproblem mit der mehrfachen Überdeckung. Beim Modifizieren der Beleuchtungsmap gegebenfalls den Stencilbuffer zur Hilfe nehmen. Hier wäre ein denkbarer Algoritmus:&lt;br /&gt;
&lt;br /&gt;
* Alle transparenten Poligone in den Zbuffer rendern. Dabei für alle Poligone, deren  doppelte Filterung zu Fehlern führen kann mit verschiedenen Stencilwerte schreiben.&lt;br /&gt;
* Zbuffer und Colorbuffer Löschen. &lt;br /&gt;
* Helligkeitsmap in den Colorbuffer kopieren.&lt;br /&gt;
* Alle nicht transparanten Objekte in den Zbuffer Rendern. &lt;br /&gt;
* Alle transparenten Poligone mit den gleichen Stencilwerten wie im erstem Pass rendern. Die Bedingung ist, dass nur Polygone in den Zbuffer geschrieben werden, bei den Stencilwerte nicht mit den Stencilbuffer übereinstimmen. Die vordersten Polygone werden so aussortiert und nur die zweite Schicht landet im Zbuffer.&lt;br /&gt;
* Im letztem Rendervorgang müssen die gefilterten Lichtfarben der Transparenten Polygone in den Colorbuffer geschrieben werden. Die Bedingung ist das die Stencilwerte übereinstimmen müssen.&lt;br /&gt;
&lt;br /&gt;
Auch wenn es wie ein großer Mehraufwand aussieht, ist der Anteil der transparenten Poligone doch eher gering. So das deren dreifacher Overdraw kaum eine Rolle spielt. Im Finalem Renderdurch gang gibt es bei den transparenten Polygonen noch eine Besonderheit: Stimmt die Entfernung aus der Shadowmap mit der Entfernung der Lichquellen (fast) überein, so wird das Poligon mit dem Licht aus der Colormap belauchtet. Ist die Entfernung aus der Shadowmap jedoch größer als die entfernung zu lichquellen, enthällt die Colormap die gefilterte Farbe des Lichtes hinter dem Poligon. Für die beleutung des Poligon muss also das Licht der Lichquelle benutzt werden. Sinvoll ist es die helligkeit für diesen Fall im Alphawert der Colormap zu Speichern.&lt;br /&gt;
&lt;br /&gt;
Ansonsten noch ein paar Vorschläge:&lt;br /&gt;
* Objekte die aus dem gleichem Glas sind und auch einfarbig. Sollten mit dem gleichem Stencilwert verarbeitet werden. So sieht z.B. das gefärbte Licht einer zweifach durchstrahlten leicht gefäbten Glasskuppel natürlicher aus als ein Vollschatten. Auch wenn das Licht korrekter weise zwei mal hätte gefiltert werden müssen. &lt;br /&gt;
* Eventuel macht es sind mehrfarbige Objekte in mehrfache einfarbige Objekte zu zerlegen.&lt;br /&gt;
* Komplexe Mehrfachfilterungen sollten vermieden werden oder so gewählt werden, das sie natürlich ausehen. Gute Filter wären komplementärfarben, da dort ein echter Schatten erzeugt wird. Schlechte Kombinationen wären unter anderem Rot+Gelb, Blau+Gelb, usw...&lt;br /&gt;
* Um von den Farbfehlern abzulenken, farbige Objekte in einer rotverschobenen Farbe flourezieren lassen. (Violet-&amp;gt; Blau -&amp;gt; Grün -&amp;gt; Gleb -&amp;gt; Organge -&amp;gt; Rot) Durch blau gefärbte Fenster, blau gefilterte Licht welches Dinge grün aufleuchten lässt nimmt einem jeder PC Modder ab...&lt;br /&gt;
&lt;br /&gt;
===Schattenmap durch eine Heightmap modifizieren===&lt;br /&gt;
Auch wennich hierzu noch kein Beispiel haben, ist es möglich gl_FragDepth mit hilfe einer Heightmap zu modifizieren. Prinzipiell entspricht dies einem einfachem Offsetmapping. Damit wäre durchaus eine Selbstschattierung von Bumpmaps möglich.&lt;br /&gt;
&lt;br /&gt;
===Zweite parabolische Map vermeiden===&lt;br /&gt;
Lichtquellen, die nur in eine Richtung Licht werfen können, wie z.B. Spotlichter oder Lichter, die in Bodenähe oder Wandnähe befestigt sind, benötigen keinen vollständig erfassten Tiefenraum. Die Parabolische Map kann problemlos herein oder herausskaliert werden, so das Öffnungswinkel von 0 bis ca 240 Grad möglich sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Das verkleinern des Öffnungswinkels für zusätzliche Spotlichter ermöglicht auch kleinere Tiefenmaps, die in die 9 Zwischenräume der großen gepackt werden können. Die Zwischenräume können noch Maps mit einem Durchmesser von 40% der großen Maps aufnehmen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Texturelookups vermeiden===&lt;br /&gt;
Wenn das Skalarprodukt von normalvec und -lightdir negativ ist, dann ist die Oberfläche von der Lichtquelle abgewandt und Berechnungen für die Lichquelle können komplett übersprungen werden. Diverse Multiplikationen und vorallem Texturelookups können so übersprungen werden. Besondere aufwendige Algorithmen wie selbstschattierende Bumpmaps, können so deutlich Beschleunigt werden. &lt;br /&gt;
&lt;br /&gt;
Für die Beleuchtung sollte dann allerdings auch folgende Zeile verwendet werden. (Das Skalarprodukt von vor der if Abfrage aber umbedingt wiederverwerten!) &lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;&lt;br /&gt;
  light += gl_LightSource[0].diffuse * max(dot(normalvec, -lightdir), 0.0);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Reichweite der Lichtquellen=== &lt;br /&gt;
Leider bietet OpenGL nicht direkt die Möglichkeit die maximale Reichweite einer Lichquelle anzugeben. In den Shadern wird zur Zeit der Wert 15.0 als maximale Entfernung zur Lichtquelle verwendet. Für ein einfaches Programm ist es sicher ausreichend, ansonsten macht es Sinn diesen Wert durch eine Unformvariable zu ersetzten, oder um mehr Flexibiltät zu bekommen durch ein Array aus 8 Uniformfloats.&lt;br /&gt;
&lt;br /&gt;
===Oversampling der Schattenmap===&lt;br /&gt;
Die Qualität lässt sich dadurch mehrere Samples auf der Schattenmap verbessern. Das folgende Codefragment nimmt 3 statt des einem Samples und glättet die Ränder des Schattens. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;glsl&amp;quot;&amp;gt;const float pof =1.0 /4096.0 *0.7;&lt;br /&gt;
vec4 shadow = step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol +vec2(pof,0)).r );&lt;br /&gt;
shadow += step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol+vec2(-pof/2.0,-pof/1.2) ).r );&lt;br /&gt;
shadow += step (length(lightvec)/15.0 -0.05, texture2D(Shadowmap, parabol+vec2(-pof/2.0,pof/1.2)).r );&lt;br /&gt;
light += shadow * 0.33 * gl_LightSource[LightNum].diffuse * abs(dot(normalvec, lightdir));&amp;lt;/source&amp;gt;&lt;br /&gt;
Durch 9x Oversampling lässt sich schon eine sehr gute Qualität ereichen, sorgt aber bei 8 Lichtquellen durch die 72 Texturelookups für einen Zusammenbruch der Framerate.&lt;br /&gt;
Wichtig ist auch, dass man beachtet, dass die dualparaboliden Maps an Ihren Ränden undefiniert sind und so zu Artefakten kommen kann wenn man außerhalb des gültigem Bereichs sampled. Eine Möglichkeit wäre einen Bereich zu erfassen, der etwas größer als 180 Grad ist, um am Rand zusätzliche Texel zu schaffen.&lt;br /&gt;
&lt;br /&gt;
===Ein zusätzlicher Renderpass===&lt;br /&gt;
Nach dem die Tiefenmap gerendert würde, wäre es möglich in einem weiterem Framebufferobjekt eine zusätzliche Map zu rendern, in der mit Hilfe einer Kantenerkennung die Helligkeit der Softshadows vorberechnet wird. Auch hier muss berücksichtigt werden, dass die dualparaboliden Maps einen Übergang haben.&lt;br /&gt;
&lt;br /&gt;
===Dynamische Lichter in statische Lightmaps Rendern===&lt;br /&gt;
Wenn sich Lichtquellen nicht relativ zur Umgebung nicht bewegen, ist es möglich sie in eine Lightmap zu rendern. Unter der Annahme, dass Lightmapkoordinaten vorhanden sind (ohne geht es echt nicht gut), müssen diese nur per Vertexshader an den Pixelshader weitergegeben werden. Im Pixelshader kann dann wie im final.frag die Helligkeit berechnet werden und in der Lightmap abgespeichert werden.&lt;br /&gt;
Es ist immer noch möglich, das dynamische Objekte einen Schatten werfen: Es werden nur noch die beweglichen Objekte in die Tiefenmap gerendert. Im Schatten wird dann einfach das Licht der im Schatten liegenden Lichtquelle subtraiert.&lt;br /&gt;
&lt;br /&gt;
===Statische Anteile in den Schattenmaps===&lt;br /&gt;
Es ist möglich mit einer zusätzlichen Matrix die Tiefenmaps zu den Weltkoordinaten auszurichten. Statische Anteile können dann aus einer zweiten Tiefenmap kopiert werden. Ein wenig problematisch ist das Entfernen der Rotation aus der gl_ModelViewMatrix. Das größte Problem ist, das die Positionen der Lichquellen bereits mit der gl_ModelViewMatrix multipliziert sind. Die einfachste Lösung ist, aus den den Rotationswinkeln eine neue Matrix zu erechnen, mit dessen Hilfe die Schattenvektoren für die Texturkoordinatenberechnung zurückgedreht werden. Diese Matrix sollte dann als Uniformvariable übergeben werden.&lt;br /&gt;
Wenn die Schatten durch einen zusätzlichen Renderdurchgang gefiltert werden. Ist es sinvoll die Maps erst hier zu vereinen. Von beiden Tiefenmaps muss nur immer der kleinere Wert genommen werden.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tool&amp;diff=24658</id>
		<title>Tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tool&amp;diff=24658"/>
				<updated>2010-01-31T09:52:29Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* 2D/Texturen-Tools */  Alten Link zhu Explosion Generator entfernt (Seite offline) und durch Link zu eigenem ersetzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Kostenlose Tools ==&lt;br /&gt;
&lt;br /&gt;
Kostenlose für OpenGL/3D-Spieleprogrammierung/3D-Grafik relevante Tools und Programme.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
![http://www.realtech-vr.com/glview/ GLView]&lt;br /&gt;
|Tool welches Informationen über die auf einem Rechner vorhandene GL Implementation extrahiert und anzeigt. Unter anderem von welchem Hersteller die Implementation stammt und welche Extensions/GL-Version unterstützt wird.&lt;br /&gt;
|-&lt;br /&gt;
![http://delphi3d.net/hardware/index.php GLinfo]&lt;br /&gt;
|Tool welches Informationen über die auf einem Rechner vorhandene GL Implementation extrahiert und anzeigt. Es werden auch technische Informationen wie maximal zulässige Texturgröße angezeigt. Das Tool generiert ein Logfile was, wenn gewünscht, auch in die '''OpenGL Hardware Registry''' eingetragen werden kann.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mathematik/Physik ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
![http://www.amd.com/acml/ ACML]&lt;br /&gt;
| Bibliothek mit hochoptimierten Befehlen für Mathematische Berechnungen (C++, gut dokumentiert, AMD-optimiert)&lt;br /&gt;
|-&lt;br /&gt;
! [http://math-atlas.sourceforge.net/ ATLAS]&lt;br /&gt;
| Bibliothek basierend auf BLAS und LAPACK (C++/Fortran)&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.netlib.org/blas/ BLAS]&lt;br /&gt;
| Bibliothek mit optimierten Befehlen für lineare Algebra (Fortran 77)&lt;br /&gt;
|- &lt;br /&gt;
! [http://www.partow.net/projects/fastgeo/index.html FastGeo]&lt;br /&gt;
| Bibiothek mit optimierten mathematischen Funktionen die direkt für Delphi/FreePascal entwickelt wurde. Prozedural aufgebaut (nicht OOP)&lt;br /&gt;
|- &lt;br /&gt;
! [http://www.fftw.org/ FFTW]&lt;br /&gt;
| Bibliothek mit optimierten Befehlen für FFTs (als DLL mit C++/Pascal-Header erhältlich)&lt;br /&gt;
|- &lt;br /&gt;
! [http://www.netlib.org/lapack/ LAPACK]&lt;br /&gt;
| Bibliothek mit optimierten Befehlen für lineare Algebra (Fortran 77)&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.ageia.com/novodex_downloads.html Novodex Engine]&lt;br /&gt;
| Eine der größten Physik-Engines&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.library.cornell.edu/nr/bookcpdf.html Numerical Recipes]&lt;br /&gt;
| Dokumentation mit vielen Beispielen zur Funktionsweise verschiedenster Algorythmen; die Bibel der Numeriker schlechthin&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2D/Texturen-Tools ===&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.lmnopc.com/bitmapfontbuilder/ Bitmap Font Builder] &lt;br /&gt;
| Erstellt 2D-Fonttexturen, mit diversen Einstellungsmöglichkeiten. Exportiert zudem auch noch die Dimensionen der Buchstaben.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.saschawillems.de/?page_id=253 Explosion Texture Generator]&lt;br /&gt;
| Erstellt eine 2D-Textur mit einer animierten Explosion. Ideal für animierte Billboard-Explosionen.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.planetside.co.uk/terragen/ Terragen]&lt;br /&gt;
| Ein besseres Tool zum Erstellen realistischer Skybox-Texturen gibt es nicht.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.planetside.co.uk/terragen/tg2/tech_preview.shtml Terragen 2 Technology Preview]&lt;br /&gt;
| Obwohl noch die Technology Preview schon gut geeignet um sowohl Skyboxes als auch Terrain-Texturen mit Normalmaps zu rendern.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.saschawillems.de/?page_id=92 TerrTexGen]&lt;br /&gt;
| Tool zur Erstellung von Terraintexturen. Oft und gerne genutzt.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.bundysoft.com/L3DT/ L3DT]&lt;br /&gt;
| Der 'Large 3D Terrain Generator' (L3DT) erzeugt hochwertige 16bit Graustufen [[Heightmap|Heightmaps]] sowie Alphamaps und darf auch in der kostenlosen Version kommerziell genutzt werden.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.texturesynthesis.com/texture.htm MRFsynthesis]&lt;br /&gt;
| Automatische Generierung von hochwertigen, kachelbaren Texturen mit beliebiger Auflösung aus Fotos oder anderen Quelltexturen. Ausführliche Beschreibung im [[Texturesynthesis|Texturesynthesis-Artikel]].&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.logarithmic.net/pfh/resynthesizer Resynthesizer]&lt;br /&gt;
| Ein Plugin für '''GIMP''' mit ähnlichen Funktionen wie '''MRFsynthesis''', jedoch mehr Features und höherer Geschwindigkeit. Ausführliche Beschreibung im [[Texturesynthesis|Texturesynthesis-Artikel]].&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.gimp.org/ GIMP]&lt;br /&gt;
| GNU Image Manipulation Tool. Gutes kostenloses Bildbearbeitungsprogramm das sich nicht unbedingt vor Photoshop &amp;amp; Co. (mal abgesehen von der UI) verstecken muss.&lt;br /&gt;
|-&lt;br /&gt;
! [http://web.bethere.co.uk/terabit/ Tattoo]&lt;br /&gt;
| Ein sog. 3D-Paint Tool, mit dem man direkt auf ein Modell zeichnen kann und so Texturen erstellen kann. Besonders für Leute die Probleme haben 2D-Texturen für komplexe Modelle zu erstellen ein tolles Programm. Das Tool unterstützt viele Modell- und Texturformate und ist für die nicht-kommerzielle Nutzung umsonst.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.lysator.liu.se/~kand/caustics/ Caustics Generator]&lt;br /&gt;
| Ein sehr schönes Programm, dass Relief-Texturen aller Colleur erzeugen kann. Das Programm eignet sich auch zum automatischen Berechnen animierter Sequenzen, wie zum Beispiel einer Wasserbewegung in 30 Frames. Sowohl die Ränder als auch die Übergänge zeitlich werden so erstellt, dass alle Übergänge fließend wirken.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 3D-Tools ===&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.delgine.com/ DeleD]&lt;br /&gt;
| Mit Delphi entwickelter 3D-Editor, der speziell auf Spieleentwickler ausgerichtet ist. Zwar noch in Entwicklung, aber bereits mehr als brauchbar.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.anim8or.com/ Anim8or]&lt;br /&gt;
| Kostenloser 3D-Modeller, allerdings fehlen (noch) einige nützliche Features wie z.B. UVW-Mapping.&lt;br /&gt;
|-&lt;br /&gt;
! [http://sourceforge.net/projects/wings/ Wings 3D]&lt;br /&gt;
| Freeware Polygon Modeller. Obwohl ihm noch einige Features fehlen, ist er einen Blick wert.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.blender3d.org/ Blender3D]&lt;br /&gt;
| Sehr ausgereiftes und komplexes 3D Tool mit frei gestaltbarer Oberfläche. &lt;br /&gt;
* [http://blendpolis.serverpool.org/f/article.php blend.polis]- Deutsche Blender Seite mit Tutorials&lt;br /&gt;
* umfangreiches [http://www.trcoding.de/informatik/blender/index.html Einsteiger Tutorial]&lt;br /&gt;
* '''sehr gute''' [http://blenderunderground.com/category/video-tutorials/ Video-Tutorials] (englisch)&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.fluidstudios.com/ FSRad]&lt;br /&gt;
|Auf Lightmaps spezialisierter Radiosity Prozessor. &lt;br /&gt;
|-&lt;br /&gt;
! [http://www.delphigl.com/forum/viewtopic.php?t=2421 gl3ds]&lt;br /&gt;
| '''3ds''' Model-Loader (DGL-Projekt)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Shaderentwicklung  ===&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.ati.com/developer/rendermonkey/index.html RenderMonkey 1.5]&lt;br /&gt;
| ATI's HLSL-Shader IDE. Jetzt auch endlich mit Support für glSlang.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.typhoonlabs.com/ OpenGL Shader Designer]&lt;br /&gt;
| Gute Shader IDE für glSlang.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Sound ===&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.buzzmachines.com/ BUZZ]&lt;br /&gt;
| Komplettes Soundstudio für E-Sounds. Es existieren unmengen Plugins welche das verhalten von allen denkbaren Soundeffekten und Soundgeneratoren imitieren können.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.bluemoon.ee/history/scwin/index.html Sound Club]&lt;br /&gt;
| Eine Art &amp;quot;Tracker&amp;quot; mit recht vielen Features, der dass Erstellen von Musik einfach macht. War mal Shareware, ist inzwischen aber als Freeware erhältlich.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www-personal.monash.edu.au/~myless/catnap/pamela/index.html PAMELA]&lt;br /&gt;
| Vergleicht in Waveform abgespeicherte Sprache mit einem eingegebenem Text und ermittelt an welchem Zeitpunkt welche Laute vorkommen, und erstellt daraus eine Liste. Mit Hilfe dieser Liste kann man seine Figuren lippensynchron animieren.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.madtracker.org/ MadTracker]&lt;br /&gt;
| Sehr ausgereifter, professioneller Tracker. Kann auch FastTracker-Module (*.xm) bearbeiten. Wer modulbasierte Musik in seinen Programmen nutzen will, sollte sich MadTracker auf jeden Fall ansehen.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.modplug.com/ ModPlugTracker]&lt;br /&gt;
| Sehr ausgereifter und vielseitiger Tracker. Kann alle gängigen Module (*.mod, *.nst, *.s3m, *.stm, *.xm, *.it, *.mtm, *.okt, *.mdl, *.669, *.far) bearbeiten, sowie Midis und Waves importieren und exportieren. Auch einen Download wert: ModPlugPlayer, der kleine Bruder vom Tracker, der die oben genannten Module abspielen kann und das mit einer Vielzahl von Funktionen. So kann z.B. der Resampling-Mode eingestellt werden, oder die Geschwindigkeit des abgespielten Mods, sowie die Tonhöhe über Schieberegler verändern. Die beiden Programme können auch komprimierte Mods (*.mdz, *.s3z, *.xmz, *.itz), sowie die Unreal-Module (*.utx) bearbeiten.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Programmierung/IDE/Allgemein ===&lt;br /&gt;
&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!width=&amp;quot;25%&amp;quot;| Name, Link&lt;br /&gt;
!width=&amp;quot;75%&amp;quot;| Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.prestosoft.com/ps.asp?page=edp_examdiff ExamDiff]&lt;br /&gt;
| Beschreibung: Visuelles Vergleichsprogramm für Text/Quellcode Dateien um Veränderungen an solchen Dateien zu suchen. (Freeware nur Pro Version kostenpflichtig)&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.gexperts.org/ GExperts]&lt;br /&gt;
| Geniale IDE-Erweiterung (inkl. diverser Tools) um die Produktivität bzw. Funktionalität von Delphi zu verbessern/erweitern. &lt;br /&gt;
|-&lt;br /&gt;
! [http://www.automatedqa.com/downloads/memproof.asp MemProof]&lt;br /&gt;
| Ein Tool für diverse Borland Entwicklungsumgebungen, welches nach Speicherlecks sucht.&lt;br /&gt;
|-&lt;br /&gt;
! [http://www.winmerge.org/ WinMerge]&lt;br /&gt;
| Externes Datei-Vergleichen zum visuellen Zusammenführen von Konflikten.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24624</id>
		<title>HUD</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24624"/>
				<updated>2010-01-18T19:39:45Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Verwendung */  Link auf GUI_Leitfaden geändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein '''Heads Up Display''' ist eine Anzeige welche ins Sichtfeld des Nutzers eingeblendet wird.&lt;br /&gt;
&lt;br /&gt;
==Herkunft==&lt;br /&gt;
Ursprünglich stammt das HUD aus der Luftwaffe, wo es schon seit ca. den 70er Jahren eingesetzt wird um wichtige Informationen direkt im Blickfeld des Piloten anzuzeigen. Dies geschieht entweder über ein Display am Helm (daher auch &amp;quot;Heads up display&amp;quot;) oder (neuer) durch Projektion der Daten auf die Scheibe des Cockpits selbst. So muss der Pilot seinen Blick nicht vom wichtigen Kampfgeschehen abwenden sondern kann sich auf dass konzentrieren was um ihn rum geschieht, im Gegensatz zu alten Flugzeugen, bei denen der Pilot permanent alle möglichen Instrumente im Auge behalten musste.&lt;br /&gt;
&lt;br /&gt;
Inzwischen findet diese Technik auch Verwendung in Fahrzeugen, momentan allerdings eher in der gehobenen Klasse (die Dodge Viper besitzt z.B. ein zuätzliches HUD mit Geschwindigkeit, Gang, Drezhal, dass auf die Scheibe über dem Lenkrad projeziert wird).&lt;br /&gt;
&lt;br /&gt;
==Verwendung==&lt;br /&gt;
Da man bei Videospielen oder anderen 3D-Anwendungen fast immer den kompletten Bildschirm im Blickfeld hat, hat sich der Begriff HUD hier auch schnell eingebürgert und wird hier für fast alle Anwendungsgebiete verwendet, egal ob man in einem Jump'n'Run nur Leben und Punkte anzeigt oder in einer komplexen Simulation ein echtes HUD emuliert.&lt;br /&gt;
&lt;br /&gt;
Allerdings spricht man eigentlich nur in Actionspielen und Simulationen von einem HUD. Damit ist dann eine Anzeige gemeint die permanent die gleichen Informationen anzeigt und dabei nur wenige Elemente besitzt. Bei einem Strategiespiel, dass sehr viele Informationen anzeigt und zusätzlich noch Fenster oder weitere Bildschirme mit mehr Informationsmaterial anzeigt, spricht man daher nicht mehr von einem HUD, sondern von einer [[GUI_Leitfaden|GUI]] (Graphical User Interface - Grafische Benutzerschnittstelle).&lt;br /&gt;
&lt;br /&gt;
==Realisierung==&lt;br /&gt;
HUDs werden üblicherweise im [[glOrtho|Othogonal/2D-Modus]] realisiert. Es gibt natürlich auch Ausnahmen, da es hier keinerlei feste Definitionen gibt. In Flugsimulatoren z.B. wird das HUD natürlich wie in der Realität auf z.B. die dreidimensionale Oberfläche des Cockpits projeziert, nachdem es üblicherweise in eine Textur gerendert wurde.&lt;br /&gt;
&lt;br /&gt;
==Kritik und Alternativen==&lt;br /&gt;
Ein HUD ist immer etwas nützliches. Allerdings wiederstrebt die Darstellung der typischen Elemente eines HUDs oft dem Trend des fortschreitenden Realismus, denn in der Realität besitzt man ja auch keine Statusanzeien über seine eigene Lebensenergie o.ä. Daher gibt es hier diverse Entwickler die versuchen ein normales HUD zu vermeiden um den Spieler nicht mit realitätsfremden Einblendungen aus der Immersion zu reissen. Ein sehr gutes und aktuelles Beispiel ist der Titel Dead Space, bei dem man kein typisches HUD mehr anzeigt. Stattdessen werden alle wichtigen Informationen direkt auf den Objekten angezeigt. Lebensnergie wird über einen blauen Schlauch am Rücken der Spielfigur dargestellt, während der Munitonsvorrat direkt an der Waffe ersichtlich ist (je nach Modell unterschiedlich). Dies ermöglicht die Anzeige wichtiger Informationen ohne den Spieler über ein entfremdendes HUD aus der Atmosphäre zu reissen. Diesen Ansatz verfolgen auch andere Spielentwickler, und er dürfte in Zukunt mehr an Bedeutung gewinnen. &lt;br /&gt;
&lt;br /&gt;
[[Datei:hud_deadspace.jpg]]&lt;br /&gt;
&lt;br /&gt;
Es gibt natürlich weitere Beispiele für Statusinformationen die man ohne HUD darstellen kann. Darunter fallen z.B. Waffenmagazine um den Spieler über seinen Munitionsstand zu informieren. Hier gibt es Waffen bei denen man dies direkt erkennen kann (z.B. die FN P90) oder Spiele bei denen man per Tastendruck das Magazin einer Waffe prüfen kann (z.B. bei einem Horroshooter von Sega, der als Beispiel hier nicht aufgeführt werden darf da er in Deutschland verboten wurde). Inzwischen hat es sich zumindest bei Shootern auch durchgesetzt dass man keine traditionelle Anzeige der Lebensenergie mehr hat, sondern direkt z.B. über einen sich dunkelrot färbenden Bildschirm über den aktuellen Gesundheitszustand informiert wird. &lt;br /&gt;
&lt;br /&gt;
Natürlich kann man Statusinformationen auch über den Ton &amp;quot;darstellen&amp;quot;, also z.B. auf welchem Untergrund man sich bewegt und wie leicht man dadurch hörbar ist (sehr gut in &amp;quot;Rainbow Six : Ravenshield (©Ubisoft)&amp;quot; implementiert, so gut dass man über die Schrittgeräusche und deren Dämpfung etc. ein Spiel gewinnen kann), oder auch durch Herzklopfen, welches angibt wie schwer der Charakter verletzt ist. Hier ist es natürlich etwas schwerer als über den optischen weg, da der Spieler erstmal erkennen muss wann genau welcher Ton welchen Zustand darstellt. &lt;br /&gt;
&lt;br /&gt;
Aber eine Kombination aus optischem und akkustischem Feedback kann fast immer ein typisches HUD erstezen und trägt stark zur Steigerung der Spielatmosphäre bei.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Kompromiss der häufig Anwendung findet ist übrigens das temporäre Ausblenden des HUDs. So kann man z.B. Lebensnergie usw. ausblenden wenn sich der Charakter nicht im Kampf befindet.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
[[Datei:hud_jagdgeschwader.jpg]] [[Datei:hud_cardemo.jpg]]&lt;br /&gt;
&lt;br /&gt;
Links das Bild eines HUDs aus dem Spiel &amp;quot;Jagdgeschwader&amp;quot;, einem Arcadeflugspiel. Dort ist das HUD unterteilt, und zeigt neben den verbleibenden Leben eine rotierende Karte mit Gegner- und Spielerposition und weiteren wichtigen Items, sowie (links unten) Statusinformationen zum Flugzeug des Spielers (Lebensenergie, Temperatur der Waffen und Geschwindigkeit).&lt;br /&gt;
&lt;br /&gt;
Rechts davon ein &amp;quot;kombiniertes&amp;quot; HUD, das alle wichtigen Informationen in einem Bildschirmabschnitt unterbrint. Da es sich hier um eine Fahrzeugdemo handelt ist dieses HUD der Anzeigetafel eines typischen Autos nachempfunden und beinhaltet typische Elemente wie Drezahlmesser, Tacho und Ganganzeige.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24600</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24600"/>
				<updated>2010-01-16T11:25:08Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Sonstige Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft (basierend auf S3Tc). Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''[[Mipmap]]s direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch weitere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlegen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farbübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbübergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS unterstützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit 16-Bit pro Farbkanal (max. 64 Bit) als auch Formate mit 32-Bit pro Farbkanal (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für [[Normalmap]]s) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
(Obiger Screenshot zeigt den Exportdialog des NVidia-Plugins für Adobes Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Adobe Photoshop : [http://developer.nvidia.com/object/photoshop_dds_plugins.html Offizielles Plugin von NVidia]&lt;br /&gt;
* GIMP : [http://nifelheim.dyndns.org/~cocidius/normalmap/ Open Source Normalmap Plugin] (allerdings mit weniger Funktion als das Plugin für Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Delphi/Pascal ===&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen. Wie der grundlegende Quellcode für einen DDS-Loader aussieht kann man aus [http://developer.nvidia.com/object/texture_compression_OpenGL.html diesem Dokument] von NVidia entnehmen (C++).&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
Damit man komprimierte Texturen in OpenGL nutzen kann muss die Grafikkarte über die Extension [[GL_ARB_texture_compression]] verfügen. Da DDS allerdings auf S3Tc aufbaut, dürfte diese Extension auf allen Grafikkarten die innerhalb der letzten 8 Jahre produziert wurden funktionieren.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sonstige Links ==&lt;br /&gt;
[http://developer.nvidia.com/object/nv_texture_tools.html Texturetools von NVidia] Umfangreiches Paket an Bibliotheken, Kommandozeilentools und Dokumentation rund um DDS&lt;br /&gt;
&lt;br /&gt;
[http://developer.amd.com/gpu/compressonator/Pages/default.aspx The Compressonator] Texturkompressionsanwendung von ATI&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24599</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24599"/>
				<updated>2010-01-16T11:24:23Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft (basierend auf S3Tc). Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''[[Mipmap]]s direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch weitere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlegen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farbübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbübergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS unterstützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit 16-Bit pro Farbkanal (max. 64 Bit) als auch Formate mit 32-Bit pro Farbkanal (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für [[Normalmap]]s) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
(Obiger Screenshot zeigt den Exportdialog des NVidia-Plugins für Adobes Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Adobe Photoshop : [http://developer.nvidia.com/object/photoshop_dds_plugins.html Offizielles Plugin von NVidia]&lt;br /&gt;
* GIMP : [http://nifelheim.dyndns.org/~cocidius/normalmap/ Open Source Normalmap Plugin] (allerdings mit weniger Funktion als das Plugin für Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Delphi/Pascal ===&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen. Wie der grundlegende Quellcode für einen DDS-Loader aussieht kann man aus [http://developer.nvidia.com/object/texture_compression_OpenGL.html diesem Dokument] von NVidia entnehmen (C++).&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
Damit man komprimierte Texturen in OpenGL nutzen kann muss die Grafikkarte über die Extension [[GL_ARB_texture_compression]] verfügen. Da DDS allerdings auf S3Tc aufbaut, dürfte diese Extension auf allen Grafikkarten die innerhalb der letzten 8 Jahre produziert wurden funktionieren.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sonstige Links ==&lt;br /&gt;
[http://developer.nvidia.com/object/nv_texture_tools.html Texturetools von NVidia] Umfangreiches Paket an Bibliotheken, Kommandozeilentools und Dokumentation rund um DDS&lt;br /&gt;
[http://developer.amd.com/gpu/compressonator/Pages/default.aspx The Compressonator] Texturkompressionsanwendung von ATI&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=MipMaps&amp;diff=24598</id>
		<title>MipMaps</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=MipMaps&amp;diff=24598"/>
				<updated>2010-01-15T09:51:12Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Wofür steht das MIP in MipMapping&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mip Mapping (MIP = ''multum in parvo'' = vieles im Kleinen), ist eine Technik welche die Darstellungsqualität von Bildern ([[Texturen]]) verbessert, wenn diese kleiner als in der ursprünglichen Größe dargestellt werden (bezogen auf die Auflösung des Bildes in Pixeln). Als angenehmer Nebeneffekt wird normalerweise auch weniger Rechenzeit benötigt, wenn ein Bild mit Hilfe von MipMaps verkleinert dargestellt wird. Dies wird jedoch durch einen vergrößerten Speicherplatzverbrauch zum Ablegen der MipMaps im Speicher (entweder Hauptspeicher oder Grafikkartenspeicher) ''erkauft''.&lt;br /&gt;
&lt;br /&gt;
Wird ein Bild ohne MipMaps verkleinert dargestellt, dann erscheint dieses Bild (besonders bei einer [[Animation]]) oft unruhig, da sich die einzelnen Pixel oft verändern. Den Effekt kann man mit Rauschen oder Krisseln beschreiben und ist in der Regel unerwünscht. Es rührt daher, dass durch die Verkleinerung ausgehend vom Orginalbild die Frequenzen  der Zeilen und Spalten nicht korrekt behandelt werden.&lt;br /&gt;
&lt;br /&gt;
Soll aus den [[Texel|Texeln]] der Textur das Zielpixel berechnet werden, so wird man in der Regel mehrere Texel zur Berechnung verwenden (siehe [[bilinear|bilineares Filtern]]). Benutzt man dabei statt der orginal Textur eine Mipmap so spricht man auch von [[trilinear|trilinearer Filterung]]. Man kann die Ergebnisse des trinilearen Filterns sogar noch verbessern, indem man den [[Anisotropes Filtern|anisotrophischen Filteralgorithmus]] verwendet.&lt;br /&gt;
Das Gegenteil zum Mipmapping ist die [[Interpolation]] bei der Vergößerung von Bildern.&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Dies ist das Bild in der orginalen Größe von 256x256 Pixeln: [[Bild:Sf256.jpg|San Francisco Skyline]]&lt;br /&gt;
&lt;br /&gt;
Soll nun dieses Bild in 64x64 Pixeln dargestellt werden, so wird normalerweise einfach nur jede vierte horizontale Zeile und jede vierte vertikale Spalte angezeigt: [[Bild:Sf64u.jpg]] Man kann erkennen, dass das Resultat sehr ''pixelig'' aussieht (Für Menschen ohne 200% Sehschärfe vielleicht mit einer Bildschirm Lupe etwas nachhelfen :-). Technisch gesprochen wurden die ''hohen Frequenzen'' des orginalen Bildes nicht vor dem Verkleinern gefiltert, wodurch das Ergebnis durch [[Aliasing]] verfälscht wird.&lt;br /&gt;
&lt;br /&gt;
Beim Mipmapping werden nun verschiedene Versionen des orginalen Bildes im Speicher abgelegt, welche in der Regel jeweils um den Faktor 2 verkleinert sind. Die kleineren Bilder werden dabei jeweils korrekt ''Frequenz gefiltert'' verkleinert. Die einzelnen Verkleinerungsstufen nennt man dann '''MipMaps'''. Bei unserem Beispielbild würden folgende Bilder im Speicher abgelegt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf256.jpg]] 256x256&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf128.jpg]] 128x128&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf64.jpg]] 64x64&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf32.jpg]] 32x32&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf16.jpg]] 16x16&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf8.jpg]] 8x8&lt;br /&gt;
&lt;br /&gt;
(sowie die Größen 4x4, 2x2 und 1x1 Pixel)&lt;br /&gt;
&lt;br /&gt;
Vergleicht man nun das Bild mit 64x64 Pixeln mit dem obigen (nicht korrekt) verkleinertem, so fällt auf, dass die zweite Version wesentlich ''glatter'' aussieht. Dies sind, wie oben erwähnt, die nicht mehr vorhandenen zu hohen Frequenzen.&lt;br /&gt;
&lt;br /&gt;
==OpenGL-Funktionen==&lt;br /&gt;
&lt;br /&gt;
MipMaps können mit Hilfe der Funktion [[gluBuild1DMipmaps]] und [[gluBuild2DMipmaps]] einfach erzeugt werden, allerdings sind diese Funktionen recht langsam und man hat keinen Einfluss auf die Erstellung (und damit Qualität der MipMaps). Die MipMaps werden von der Funktion automatisch erzeugt und im Kontext der aktuellen mit [[glBindTexture]] gebundenen [[Textur]] aktiviert. Man kann die einzelnen ''Stufen'' der MipMap auch manuell erzeugen und an [[OpenGL]] übergeben, dazu ist der zweite Parameter (level) von [[glTexImage1D]], [[glTexImage2D]], [[glTexImage3D]] zu benutzen.&lt;br /&gt;
&lt;br /&gt;
Optimal ist hier jedoch ein Texturformat dass MipMaps direkt mitspeichert, wie es z.B. bei [[DDS]] der Fall ist. Dort werden die MipMaps beim Export aus dem Bildbearbeitungsprogramm in der Datei abgelegt (sofern man das wünscht) und man kann Einfluss auf deren Generation nehmen (wie sie gefiltert werden, wie viele Stufen abgelegt werden, alternativ kann man die MipMap-Stufen sogar selbst erstellen). Die MipMaps werden dann in der eigenen Anwendung direkt aus der Datei mitgeladen. Diese Methode ist flexibler und vor allem beim Laden sehr viel schneller.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=MipMaps&amp;diff=24597</id>
		<title>MipMaps</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=MipMaps&amp;diff=24597"/>
				<updated>2010-01-15T09:46:15Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* OpenGL-Funktionen */  HInweis auf DDS&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mipmapping, ist eine Technik welche die Darstellungsqualität von Bildern ([[Texturen]]) verbessert, wenn diese kleiner als in der ursprünglichen Größe dargestellt werden (bezogen auf die Auflösung des Bildes in Pixeln). Als angenehmer Nebeneffekt wird normalerweise auch weniger Rechenzeit benötigt, wenn ein Bild mit Hilfe von MipMaps verkleinert dargestellt wird. Dies wird jedoch durch einen vergrößerten Speicherplatzverbrauch zum Ablegen der MipMaps im Speicher (entweder Hauptspeicher oder Grafikkartenspeicher) ''erkauft''.&lt;br /&gt;
&lt;br /&gt;
Wird ein Bild ohne MipMaps verkleinert dargestellt, dann erscheint dieses Bild (besonders bei einer [[Animation]]) oft unruhig, da sich die einzelnen Pixel oft verändern. Den Effekt kann man mit Rauschen oder Krisseln beschreiben und ist in der Regel unerwünscht. Es rührt daher, dass durch die Verkleinerung ausgehend vom Orginalbild die Frequenzen  der Zeilen und Spalten nicht korrekt behandelt werden.&lt;br /&gt;
&lt;br /&gt;
Soll aus den [[Texel|Texeln]] der Textur das Zielpixel berechnet werden, so wird man in der Regel mehrere Texel zur Berechnung verwenden (siehe [[bilinear|bilineares Filtern]]). Benutzt man dabei statt der orginal Textur eine Mipmap so spricht man auch von [[trilinear|trilinearer Filterung]]. Man kann die Ergebnisse des trinilearen Filterns sogar noch verbessern, indem man den [[Anisotropes Filtern|anisotrophischen Filteralgorithmus]] verwendet.&lt;br /&gt;
Das Gegenteil zum Mipmapping ist die [[Interpolation]] bei der Vergößerung von Bildern.&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
Dies ist das Bild in der orginalen Größe von 256x256 Pixeln: [[Bild:Sf256.jpg|San Francisco Skyline]]&lt;br /&gt;
&lt;br /&gt;
Soll nun dieses Bild in 64x64 Pixeln dargestellt werden, so wird normalerweise einfach nur jede vierte horizontale Zeile und jede vierte vertikale Spalte angezeigt: [[Bild:Sf64u.jpg]] Man kann erkennen, dass das Resultat sehr ''pixelig'' aussieht (Für Menschen ohne 200% Sehschärfe vielleicht mit einer Bildschirm Lupe etwas nachhelfen :-). Technisch gesprochen wurden die ''hohen Frequenzen'' des orginalen Bildes nicht vor dem Verkleinern gefiltert, wodurch das Ergebnis durch [[Aliasing]] verfälscht wird.&lt;br /&gt;
&lt;br /&gt;
Beim Mipmapping werden nun verschiedene Versionen des orginalen Bildes im Speicher abgelegt, welche in der Regel jeweils um den Faktor 2 verkleinert sind. Die kleineren Bilder werden dabei jeweils korrekt ''Frequenz gefiltert'' verkleinert. Die einzelnen Verkleinerungsstufen nennt man dann '''MipMaps'''. Bei unserem Beispielbild würden folgende Bilder im Speicher abgelegt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf256.jpg]] 256x256&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf128.jpg]] 128x128&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf64.jpg]] 64x64&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf32.jpg]] 32x32&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf16.jpg]] 16x16&lt;br /&gt;
&lt;br /&gt;
[[Bild:Sf8.jpg]] 8x8&lt;br /&gt;
&lt;br /&gt;
(sowie die Größen 4x4, 2x2 und 1x1 Pixel)&lt;br /&gt;
&lt;br /&gt;
Vergleicht man nun das Bild mit 64x64 Pixeln mit dem obigen (nicht korrekt) verkleinertem, so fällt auf, dass die zweite Version wesentlich ''glatter'' aussieht. Dies sind, wie oben erwähnt, die nicht mehr vorhandenen zu hohen Frequenzen.&lt;br /&gt;
&lt;br /&gt;
==OpenGL-Funktionen==&lt;br /&gt;
&lt;br /&gt;
MipMaps können mit Hilfe der Funktion [[gluBuild1DMipmaps]] und [[gluBuild2DMipmaps]] einfach erzeugt werden, allerdings sind diese Funktionen recht langsam und man hat keinen Einfluss auf die Erstellung (und damit Qualität der MipMaps). Die MipMaps werden von der Funktion automatisch erzeugt und im Kontext der aktuellen mit [[glBindTexture]] gebundenen [[Textur]] aktiviert. Man kann die einzelnen ''Stufen'' der MipMap auch manuell erzeugen und an [[OpenGL]] übergeben, dazu ist der zweite Parameter (level) von [[glTexImage1D]], [[glTexImage2D]], [[glTexImage3D]] zu benutzen.&lt;br /&gt;
&lt;br /&gt;
Optimal ist hier jedoch ein Texturformat dass MipMaps direkt mitspeichert, wie es z.B. bei [[DDS]] der Fall ist. Dort werden die MipMaps beim Export aus dem Bildbearbeitungsprogramm in der Datei abgelegt (sofern man das wünscht) und man kann Einfluss auf deren Generation nehmen (wie sie gefiltert werden, wie viele Stufen abgelegt werden, alternativ kann man die MipMap-Stufen sogar selbst erstellen). Die MipMaps werden dann in der eigenen Anwendung direkt aus der Datei mitgeladen. Diese Methode ist flexibler und vor allem beim Laden sehr viel schneller.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24596</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24596"/>
				<updated>2010-01-13T12:04:07Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Fließkommaformate (unkomprimiert) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft (basierend auf S3Tc). Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''[[Mipmap]]s direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch weitere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlegen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farbübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbübergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS unterstützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit 16-Bit pro Farbkanal (max. 64 Bit) als auch Formate mit 32-Bit pro Farbkanal (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für [[Normalmap]]s) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
(Obiger Screenshot zeigt den Exportdialog des NVidia-Plugins für Adobes Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Adobe Photoshop : [http://developer.nvidia.com/object/photoshop_dds_plugins.html Offizielles Plugin von NVidia]&lt;br /&gt;
* GIMP : [http://nifelheim.dyndns.org/~cocidius/normalmap/ Open Source Normalmap Plugin] (allerdings mit weniger Funktion als das Plugin für Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Delphi/Pascal ===&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen. Wie der grundlegende Quellcode für einen DDS-Loader aussieht kann man aus [http://developer.nvidia.com/object/texture_compression_OpenGL.html diesem Dokument] von NVidia entnehmen (C++).&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
Damit man komprimierte Texturen in OpenGL nutzen kann muss die Grafikkarte über die Extension [[GL_ARB_texture_compression]] verfügen. Da DDS allerdings auf S3Tc aufbaut, dürfte diese Extension auf allen Grafikkarten die innerhalb der letzten 8 Jahre produziert wurden funktionieren.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24595</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24595"/>
				<updated>2010-01-13T12:03:06Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Was ist DDS? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft (basierend auf S3Tc). Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''[[Mipmap]]s direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch weitere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlegen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farbübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbübergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS unterstützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für [[Normalmap]]s) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
(Obiger Screenshot zeigt den Exportdialog des NVidia-Plugins für Adobes Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Adobe Photoshop : [http://developer.nvidia.com/object/photoshop_dds_plugins.html Offizielles Plugin von NVidia]&lt;br /&gt;
* GIMP : [http://nifelheim.dyndns.org/~cocidius/normalmap/ Open Source Normalmap Plugin] (allerdings mit weniger Funktion als das Plugin für Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Delphi/Pascal ===&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen. Wie der grundlegende Quellcode für einen DDS-Loader aussieht kann man aus [http://developer.nvidia.com/object/texture_compression_OpenGL.html diesem Dokument] von NVidia entnehmen (C++).&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
Damit man komprimierte Texturen in OpenGL nutzen kann muss die Grafikkarte über die Extension [[GL_ARB_texture_compression]] verfügen. Da DDS allerdings auf S3Tc aufbaut, dürfte diese Extension auf allen Grafikkarten die innerhalb der letzten 8 Jahre produziert wurden funktionieren.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24594</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24594"/>
				<updated>2010-01-13T12:01:52Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Hinweis auf GL_ARB_texture_compression, link auf GIMP NM plugin&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''[[Mipmap]]s direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch weitere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlegen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farbübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbübergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS unterstützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für [[Normalmap]]s) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
(Obiger Screenshot zeigt den Exportdialog des NVidia-Plugins für Adobes Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Adobe Photoshop : [http://developer.nvidia.com/object/photoshop_dds_plugins.html Offizielles Plugin von NVidia]&lt;br /&gt;
* GIMP : [http://nifelheim.dyndns.org/~cocidius/normalmap/ Open Source Normalmap Plugin] (allerdings mit weniger Funktion als das Plugin für Photoshop)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Delphi/Pascal ===&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen. Wie der grundlegende Quellcode für einen DDS-Loader aussieht kann man aus [http://developer.nvidia.com/object/texture_compression_OpenGL.html diesem Dokument] von NVidia entnehmen (C++).&lt;br /&gt;
&lt;br /&gt;
=== OpenGL ===&lt;br /&gt;
Damit man komprimierte Texturen in OpenGL nutzen kann muss die Grafikkarte über die Extension [[GL_ARB_texture_compression]] verfügen. Da DDS allerdings auf S3Tc aufbaut, dürfte diese Extension auf allen Grafikkarten die innerhalb der letzten 8 Jahre produziert wurden funktionieren.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_2D&amp;diff=24584</id>
		<title>Tutorial 2D</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_2D&amp;diff=24584"/>
				<updated>2010-01-12T17:59:50Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Welches Bildformat ist das richtige? */  DDS-Artikel verlinkt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=2D mit OpenGL - &amp;quot;Nicht jeder benötigt 3 Dimensionen&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
==Einleitung==&lt;br /&gt;
&lt;br /&gt;
Bei der Erwähnung einer API wie OpenGL denken die meisten eigentlich eher an 3D, und sind der festen (aber sehr wohl falschen) Überzeugung eine solche API sei für reine 2D-Anwendung überdimensioniert oder gar ungeeignet. Das dies nicht der Fall ist möchte ich mit diesem (vor allem an Einsteiger gerichtet, denn die Könner wissen wohl was man mit der GL so alles machen kann) Tutorial zeigen und auch gleich mit mehreren praktischen Beispielen aufweisen das 2D mit OpenGL nicht nur möglich ist, sondern auch noch sehr viel einfacher (selbst mit der GDI ist 2D komplizierter) ist und dabei jede Menge Vorteile mit sich bringt.&lt;br /&gt;
&lt;br /&gt;
==Welche Vorteile bringt mir die GL für eine 2D-Anwendung?==&lt;br /&gt;
&lt;br /&gt;
Dies ist wohl das wichtigste Kapitel und sollte zugleich auch mit diversen Vorurteilen und Missverständnissen aufräumen. Denn gerade der 3D-Bereich ist es in dem seit Jahren fast monatlich neue Techniken entworfen werden und der dafür sorgt das v.&amp;amp;nbsp;a. Grafikkarten immer leistungsstärker werden, während der 2D-Bereich seit seligen VLB-Zeiten (= Vesa-Local-Bus, alte Haudegen kennen diese Grafikkartengeneration sicherlich noch) keine Innovationen mehr erlebt hat (und warum auch? Im 2D-Bereich reicht ein gutes Bild zusammen mit passabler Darstellungsgeschwindigkeit).&lt;br /&gt;
&lt;br /&gt;
Deshalb gibt es jetzt gleich mal die wichtigsten Punkte warum man denn gerade OpenGL (D3D würde hier auch zählen, aber das haben wir GL'ler ja nicht so gerne) für die 2D-Darstellung nutzen sollte:&lt;br /&gt;
&lt;br /&gt;
*'''Hardwarebeschleunigung'''&lt;br /&gt;
:Moderne Grafikkarten können inzwischen über 200 Millionen Dreiecke pro Sekunde rendern und besitzen brachiale Füllraten jenseits der 2.000 M(Texel/Pixel)/s. Das bedeutet also das man selbst auf älteren Grafikkarten sehr komplexe 2D-Szenen mit Geschwindigkeiten jenseits der 100 FpS (= Frames per Seconds ~ Bilder pro Sekunde) darstellen kann, während man mit der GDI schon bei einfachen 2D-Grafiken Geschwindigkeitsprobleme bekommen würde.&lt;br /&gt;
&lt;br /&gt;
*'''&amp;quot;Kostenlose&amp;quot; Objektsortierung'''&lt;br /&gt;
:Eine 3D-API braucht einen Tiefenpuffer um zu erkennen ob Fragmente verdeckt sind oder nicht und damit Overdraw zu vermeiden. Eine 2D-Anwendung kann diesen Tiefenpuffer aber auch nutzen, nämlich um Objekte zu sortieren. Man nutzt dann die Z-Koordinate der Objekte (= Tiefenkoordinate) quasi als Layer um zu kennzeichnen welches Objekt auf welcher &amp;quot;Höhe&amp;quot; liegt. Wenn man also z.&amp;amp;nbsp;B. einen 2D-Topdown-Shooter entwickelt bei dem der Spieler mit seinem Flugzeug über den Boden fliegt, dann nutzt man den Z-Puffer um die API (die das dann der Hardware überlässt) seine Objekte sortieren zu lassen. Das Flugzeug bekommt dann einen niedrigen Z-Wert (=oben) und Objekte auf dem Boden einen hohen Tiefenwert (=unten/hinten). Die Sortierung übernimmt dann die Grafikkarte und wir müssen uns darum keine Gedanken machen. Würden wir die Anwendung z.&amp;amp;nbsp;B. über die GDI realisieren, müssten wir diese Objekte selbst entsprechend ihrer Höhe sortieren.&lt;br /&gt;
&lt;br /&gt;
*'''Jede Menge hardwarebeschleunigte Spezialeffekt'''&lt;br /&gt;
:Wie schon oben erwähnt haben im 3D-Bereich innerhalb der letzten Jahre sehr viele Innovationen stattgefunden. Warum sollte man diese also nicht auch für seine 2D-Anwendung nutzen? Klingt logisch und macht auch Sinn! So bietet OpenGL alle Arten von Effekten die auch in einer 2D-Anwendung nützlich sein können. Darunter solche Sachen wie den Alphatest (der dafür sorgt das maskierte Teile eines Objektes transparent sind), Blending und natürlich (auch wenn das jetzt für erfahrene GL'ler sehr trivial klingt) hardwarebeschleunigte Rotation und Skalierung; was zur Folge hat das man seine Objekte nicht für verschiedene Auflösungen in verschiedenen Größen erstellen muss. Für Fortgeschrittene gibt es dann natürlich noch solche Sachen wie Shader, mit denen man Teile der OpenGL-Pipeline durch eigene (kleine) Programme ersetzen kann (entweder in Assemblerform oder aber in der neuen GL-HLSL). Dadurch bietet sich dann ein quasi unendlich großes Spektrum an möglichen Effekten, und das wohlgemerkt alles hardwarebeschleunigt!&lt;br /&gt;
&lt;br /&gt;
*'''Plattformübergreifend'''&lt;br /&gt;
:Auch ein großer Vorteil von OpenGL. Die Tatsache das die GL unter diversen Betriebssystemen verfügbar ist (im Gegensatz zu GDI oder gar DirectX) macht die eigenen Programme recht portabel (einschränkend ist hier halt nur die Verfügbarkeit der genutzten Programmiersprache auf dem passenden OS). Unterstützt werden alle größeren Betriebssysteme wie Windows, Linux, MacOS und Solaris.&lt;br /&gt;
&lt;br /&gt;
:Ganz nebenbei wurde vor kurzem mit [http://www.khronos.org/opengles/2_X/ OpenGL ES] ein mobiler Standard für OpenGL geschaffen, wodurch es dann auch möglich ist auf mobilen Geräten (Handys, PDAs, Handhelds) OpenGL zu nutzen. Und gerade dort sind 2D-Spiele (aufgrund der oft mangelnden Leistung der Geräte) ja noch stark verbreitet.&lt;br /&gt;
&lt;br /&gt;
So viel also zu den wichtigsten Vorteilen zur OpenGL unter 2D. Natürlich gibt es noch weiter Dinge die OpenGL für 2D-Anwendungen attraktiv machen, aber allein die oben genannten Gründe sollten jedermann überzeugt haben. Und alle die wirklich mal wissen wollen wie gut OpenGL denn für solche Anwendungen geeignet ist, sollten sich unbedingt eine neuere Version des MacOS ansehen, denn das benutzt OpenGL zur Darstellung seiner GUI.&lt;br /&gt;
&lt;br /&gt;
==Und welche Nachteile gibt es?==&lt;br /&gt;
&lt;br /&gt;
Nichts was der Mensch bisher erfunden hat (mal abgesehen von der Spaltung des Atoms ;) ) hat nur Vorteile. Genauso sieht es auch aus wenn man die OpenGL für seine 2D-Anwendung nutzen will. Welche genau das sind will ich hier grob auflisten.&lt;br /&gt;
&lt;br /&gt;
*'''Ohne 3D-Beschleuniger mit passenden Treibern geht nichts'''&lt;br /&gt;
:Klingt logisch, oder? OpenGL ist eine 3D-API und da 2D nichts weiter als die (fast vollständige) Vernachlässigung der Z-Koordinate ist, kommen wir um einen 3D-Beschleuniger nicht herum, der dazu auch noch einen Treiber mitbringen muss der OpenGL unterstützt. Allerdings schritt der Fortschritt auf diesem Gebiet der IT-Technik in den letzten Jahren so rasant voran wie sonst nirgendwo, und wir werden nur sehr selten auf Rechner stoßen in denen Hardware agiert die keine 3D-Beschleunigung bietet. Ergänzend dazu sollte allerdings trotzdem immer der neuste Treiber installiert sein, denn besonders die in WindowsXP integrierten Grafikkartentreiber wurden ihrer OpenGL-Funktionalität entraubt (Man riecht hier förmlich die Konkurrenz zwischen D3D und der GL). Also ist dies im Endeffekt ein Nachteil der inzwischen kaum noch halt findet und in Zukunft total vernachlässigt werden kann.&lt;br /&gt;
&lt;br /&gt;
*'''Hardwarelimitationen'''&lt;br /&gt;
:Einer der größten Nachteile einer jeden 3D-API die auf Hardwarebasis arbeitet sind die Limitationen die die Hardware mitbringt. Jeder Grafikkartentyp hat andere, was mitunter dazu führen kann das die selbstverfassten OpenGL-Anwendungen nicht auf allen Rechnern laufen. Da wir uns in diesem Tutorial (2D ist ja recht anspruchslos) allerdings in den Niederungen der OpenGL-Funktionalität bewegen, dürfte es hier kaum Probleme geben. Einzig die Tatsache das vor allem ältere 3D-Beschleuniger mit großen Texturen Probleme haben könnte hier und da Schwierigkeiten machen. Wer aber keine Texturen größer 1024x1024 Pixel nutzt und dazu noch sparend mit dem Speicher der Grafikkarte umgeht (nicht jede Grafikkarte hat 128 Mbyte Grafikspeicher oder gar mehr). Einige Leute werden sich übrigens evtl. dadurch verunsichert fühlen das ihnen jemand gesagt hat, man könnte unter OpenGL nur Texturen nutzen die der Dimension 2^n*2^n entsprechen. Das ist grundlegend korrekt, aber wir nutzen hier einen Texturenloader der [[gluBuildMipMaps]] benutzt um [[MipMaps]] (verschiedene Detailstufen) für unsere Texturen zu erstellen. Diese Funktion schluckt jede Größe (sofern diese kleiner oder gleich dem Hardwarelimit ist) und passt die Texturen dann entsprechend an eben genanntes Limit an, also müssen wir uns um diese so oft erwähnte Limitation keine Sorgen machen. Wer zu dem Thema Hardwarelimitation mehr wissen will, der sollte unbedingt mal auf [http://www.delphi3d.net/ Tom Nuydens Seite] vorbei schauen. Dort gibt es eine riesige Datenbank in der fast alle Grafikkarten mit ihren entsprechenden OpenGL-Fähigkeiten vertreten sind.&lt;br /&gt;
&lt;br /&gt;
*'''Filtering'''&lt;br /&gt;
:Zugleich ein großer Vorteil, aber je nach Situation auch ein Nachteil. OpenGL filtert Texturen (sofern man das via GL_LINEAR so will) bilinear, was man auch tunlichst aktiviert lassen sollte (GL_NEAREST filtert nicht, sieht dann aber auch scheußlich blockig aus). Dadurch wirken Texturn meist etwas verschwommen. Ich für meinen Teil umgehe dies aber ganz einfach, denn in fast jedem Bildbearbeitungsprogramm gibt es eine Funktion mit der man ein Bild scharfzeichnen kann. Das sieht auf den ersten Blick dann zwar überzeichnet aus, aber wenn OpenGL das Bild dann als Textur bilinear filtert, heben sich Filtering und Scharfzeichnung gegenseitig fast auf. Das hat sich in meinen Anwendungen bisher bewährt und ist nicht wirklich viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
Um dieses Kapitel hier abzuschließen sei noch gesagt das man ohne 3D-Beschleuniger nicht unbedingt auf OpenGL verzichten muss. Brian Paul hat mit [http://www.mesa3d.org/ Mesa3D] nämlich ein Projekt am laufen das OpenGL-DLLs zur Verfügung stellen die komplett über die CPU ablaufen. So kann man dann OpenGL-Anwendungen mit einer etwas schnelleren CPU trotz fehlendem 3D-Beschleuniger nutzen, oder auf Funktionen ausprobieren die von der (zu alten) Grafikkarte nicht unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
==Die Grundlagen==&lt;br /&gt;
&lt;br /&gt;
Sollte sich der geneigte Leser nun also doch für die GL entschieden haben, so widmen wir uns dann jetzt den Grundlagen der 2D-Darstellung unter OpenGL. Viele Sachen die man bei einer 3D-Anwendung beachten muss, sind hier eigentlich zu vernachlässigen. Wer also schon mal eine kleine 3D-Anwendung unter OpenGL geschrieben hat wird hier sicherlich keine Problem bekommen. Da sich dieses Tutorial aber an blutige (mhh, lecker) Einsteiger richtet, versuche ich so genau und einfach wie möglich zu erklären was man machen muss und v.&amp;amp;nbsp;a. warum. Genau deshalb habe ich auch für einen Großteil der hier erwähnten Techniken im Download zu diesem Tutorial (siehe unsere Files-Sektion und dort unter VCL-Source) jeweils ein eigenes Beispielprogramm + Quellcode (und natürlich ausgiebigen Kommentaren) geschrieben. Wenn zu dem jeweiligen Kapitel ein solches im Download enthalten ist, dann steht das ''kursiv'' unter der Überschrift des Kapitels.&lt;br /&gt;
&lt;br /&gt;
==Die Projektion==&lt;br /&gt;
&lt;br /&gt;
Wie bekannt (sein sollte), besitzt OpenGL im Groben zwei wichtige Matrizen. Zum einen die Modellansichtsmatrix, in der man im Normalfall seine Szene (egal ob 2D oder 3D) rendert und (für dieses Kapitel wichtiger) die Projektionsmatrix. Diese Matrix lässt sich am besten mit der Linse einer Kamera vergleichen und legt fest wie die Objekte auf den Bildschirm projiziert werden (wer mitdenkt wird jetzt wissen warum diese Matrix so genannt wurde). In einer 3D-Anwendung setzen wir (meist über [[gluPerspective]]) eine Projektionsmatrix die dafür sorgt das unsere Objekte perspektivisch korrekt verzerrt werden (so wie es im echten Leben auch ist). Da Bilder aber mehr als tausend Worte sagen zeige ich das anhand der unteren Bildreihe, die einen Würfel an verschiedenen Positionen auf der X-Achse zeigt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_1.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Der Würfel wurde auf den beiden Bildausschnitten links und rechts jeweils um 40 Einheiten auf der X-Achse verschoben und man kann sehr gut sehen das die Seiten des Würfels perspektivisch verzerrt werden, also weiter entfernte Kanten kleiner erscheinen (wie im realen Leben, das kann man ja prima mit nem würfelähnlichem Objekt nachprüfen). Diese Art der Darstellung ist für 3D gut geeignet, aber für unseren Zweck nicht. Denn wir wollen ja das unser Objekt, egal an welcher Bildschirmposition es sich befindet, gleich aussieht.&lt;br /&gt;
&lt;br /&gt;
Dazu gibt es unter OpenGL den sog. orthogonalen Modus, der dafür sorgt das unser [[Frustum]] (Sichtkegel) nicht wie bei der 3D-Projektion kegelförmig ist (kleine Seite beim Betrachter, große Seite am Ende des Sichtfeldes), sondern wie eine Box aussieht. Für technisch interessierte hier der Vergleich zwischen dem 3D- und dem 2D-Frustum :&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_2.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir das Frustum (~Sichtbereich) für die orthogonale Projektion (also 2D) und rechts für die perspektivische Projektion (3D). In diesem Tutorial interessieren wir uns wie gesagt für ersteres Frustum, welches sich über die Funktion [[glOrtho]] erstellen lässt. Diese Funktion will von uns die Dimensionen haben die wir unserem Viewport geben wollen. Ich empfehle hier übrigens immer einen festen Wert der einer der gängigen Auflösungen (z.&amp;amp;nbsp;B. 640x480, 800x600) entspricht. Der feste Wert hat übrigens den Vorteil das unsere Anwendung von der vom Nutzer gewählten Bildschirmauflösung unabhängig ist. Wir müssen dann also nicht mehr umrechnen wo unser Objekt jetzt in der gewählten Auflösung wäre und wie groß es dort sein müsste. Dadurch das wir immer die selben virtuellen Koordinaten haben, überlassen wir der GL (bzw. der Grafikkarte) die Umrechnung. Wenn wir also eine virtuelle Auflösung von 640x480 an glOrtho übergeben, und ein Objekt zentriert bei 320x240 rendern, dann wird dieses egal in welcher Auflösung immer in der Mitte des Schirms gerendert. Die Umrechnung macht wie gesagt OpenGl (oder besser gesagt die Grafikkarte). Zusätzlich übergeben wir der Funktion dann noch die Z-Reichweite. Hier kann man beliebig wählen, und muss nicht wie in 3D darauf achten Z-Near und Z-Far so zu wählen das die Auflösung des Tiefenpuffers nicht unnötig verschwendet wird (z.&amp;amp;nbsp;B. mit einem Z-Near von 0.1 oder gar kleiner). Für Z-Near nehme ich gewöhnlich 0 und für Z-Far einen Wert der dafür sorgt das ich alle Objekte so sortieren kann das ihre Z-Position auf einen Integerwert fällt. Als kleines Codebeispiel könnte unsere Projektionsmatrix nun so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glMatrixMode(GL_PROJECTION);&lt;br /&gt;
glLoadIdentity;&lt;br /&gt;
glViewport(0,0,ClientWidth,ClientHeight);&lt;br /&gt;
glOrtho(0,640,0,480,0,128);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den optischen Vergleich zur oben erwähnten 3D-Projektion zu zeigen, gibt es wieder ein Bild des Würfels, diesmal allerdings mit 2D-Projektion:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_3.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Das sieht auf den ersten Blick zugegeben recht langweilig aus, stellt aber genau den selben Szenenverhalt dar wie die Ansicht ein paar Zeilen weiter oben. Diesmal allerdings mit der gerade besprochenen orthogonalen Ansicht, die als Grundlage für unsere 2D-Projektion dient.&lt;br /&gt;
&lt;br /&gt;
So viel also zur 2D-Projektion und hoffentlich hat das hier jeder verstanden. Die orthogonale Projektion ist ein essentieller Bestandteil einer jeden 2D-Anwendung unter OpenGL und sollte daher allen Interessierten ein Begriff sein. Falls das hier jemandem zu technisch war, im Forum werden weitergehende Fragen gerne beantwortet.&lt;br /&gt;
&lt;br /&gt;
Noch als kleiner Nachtrag: Wer sich mal die Parameter angesehen hat die glOrtho will, wird bemerkt haben das wir in obigem Quellcode (zumindest augescheinlich) Top mit Bottom verwechselt haben (sprich es sollte 0,640,480,0 statt 0,640,0,480) heißen. Das hat allerdings seine Richtigkeit, denn in OpenGL liegt der Ursprung des Koordinatensystems in der unteren linken Bildschirm(oder Fenster)ecke, wobei er bei Windows in der oberen Ecke liegt. Unter OpenGL liegt also quasi der &amp;quot;Boden&amp;quot; oben, genau umgekehrt wie unter Windows. Genau deshalb übergeben wir als &amp;quot;Oben&amp;quot; an glOrtho den eigentlichen Boden des Viewports. Das klingt verwirrend, aber ist im Endeffekt gar nicht so schwer zu behalten, besonders dann nicht wenn man sich folgende Illustration mal näher ansieht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_11.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Das sollte man immer in Hinterkopf behalten, und unter 3D ist es genauso. Während ein positiver Y-Wert Objekte in einem Windowsfenster nach unten verschiebt, geschieht unter OpenGL genau das Gegenteil. Wer sich mit dieser Tatsache nicht anfreunden kann, der kann auch gerne glOrtho dazu nutzen die 2D-Matrix von OpenGL an die Windowsgegebenheiten anzupassen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glOrtho(0,640,480,0,0,128);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und schon verhält es sich unter OpenGL genauso wie unter Windows. Positive Y-Koordinaten zeigen nach unten. Allerdings muss man hier dann auch drauf achten die gerenderten Objekte an diese Gegebenheit anzupassen. Man muss diese also quasi auf den Kopf stellen, damit sie mit der neuen Matrix korrekt angezeigt werden. Das geht aber ganz leicht, indem man beim rendern von Quads oder anderen texturierten Primitiven ganz einfach die T-Texturkoordinaten vertauscht.&lt;br /&gt;
&lt;br /&gt;
==Darstellung der 2D-Objekte==&lt;br /&gt;
&lt;br /&gt;
Einige 2D-Interessierte haben sich sicherlich schon mal im Funktionsumfang von OpenGL umgesehen und bemerkt, dass es dort eigentlich gar keine Funktionen gibt um Dinge in 2D zu zeichnen. Auf den ersten Blick sieht das auch wirklich so aus, aber man darf halt nie vergessen dass OpenGL primär für den 3D-Bereich entworfen wurde und sich 2D-Sachen dann nur über 3D-Techniken realisieren lassen. So auch die Darstellung unserer 2D-Objekte, für die wir aus genau diesem Grund eine 3D-Technik anwenden müssen, nämlich das sog. Texturemapping (Den Begriff &amp;quot;Textur&amp;quot; gibt's übrigens auch im deutschen Sprachgebrauch, aber gängiger ist die korrekte Übersetzung &amp;quot;Oberfläche&amp;quot;). Unter OpenGL werden ja alle Objekte aus verschiedenen Primitiventypen zusammengesetzt (Dreiecke, Rechtecke, usw.) und diese Objekte kann man mit einer Textur belegen die dann auf dieser Oberfläche &amp;quot;angezeigt&amp;quot; wird. Diese Textur lädt man im Normalfall aus einer vorher erstellten Bilddatei unter Nutzung eines [[Texture_Loader|Texturenloaders]] (alternativ kann man den sich natürlich auch selbst schreiben), der diese Textur für die Grafikkarte vorbereitet (also z.&amp;amp;nbsp;B. ein BMP-Bild vom BGR-Format ins RGB-Format bringt) und dann auf dieser ablegt. Danach kann diese Textur an jeder Stelle im Programm auf eine Primitve &amp;quot;geklebt&amp;quot; werden, und genauso machen wir das auch in unserer 2D-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Allerdings müssen wir keine komplexen Formen darstellen, da unsere Objekte ja nicht 3D sind, sondern (meistens) schon in einem anderen Programm erstellt (oder vorgerendert wurden) und als Bilddatei abgelegt wurde. Wir laden und stellen dann also nicht die 3D-Daten dieses Modells dar (was bei komplexen 2D-Objekten wohl eh zu viel wäre), sondern kleben diese schon fertige Bilddatei mittels einer Textur auf ein Rechteck (in der GL-Terminologie &amp;quot;Quad&amp;quot; genannt, vom Primitiventyp GL_QUADS). Hoffe mal das kam gut rüber, aber ich verdeutliche dass dann besser nochmal anhand einer kleinen &amp;quot;Bilderserie&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_4.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Oben sei mal kategorisch der Vorgang geschildert um ein vorgerendertes 3D-Objekt als Textur in seine 2D-Anwendung zu bekommen. Rechts sieht man das 3D-Modell, das dann aus der gewünschten Ansicht (im obigen Falle von der Seite) im 3D-Modellierungsprogramm gerendert wird. Dieses Rendering speichert man dann in einem Format ab das der Texturenloader verarbeiten kann, lädt dies in seine OpenGL-Anwendung und stellt dies dann auf z.&amp;amp;nbsp;B. einem Quad dar (siehe letztes Bild). Natürlich spielt es keine Rolle ob man seine 2D-Objekte vorrendert oder diese von Hand zeichnet, wobei den meisten wohl Ersteres besser von der &amp;quot;Hand&amp;quot; geht.&lt;br /&gt;
&lt;br /&gt;
===Welches Bildformat ist das richtige?===&lt;br /&gt;
&lt;br /&gt;
Bevor wir nun weiter auf das Thema eingehen kümmern wir uns um die '''Frage nach dem richtigen Bildformat''' für unsere Texturen. Bildformate gibt's wie Sand am Meer, aber für unseren Zweck eignen sich nur sehr wenige (eigentlich nur ein einziges). Ich zähle die verbreitetsten Formate kurz auf und sag auch warum (oder warum nicht) und wofür man diese verwenden kann:&lt;br /&gt;
&lt;br /&gt;
*'''Joint Photographic Experts Group (*.jpg; *.jpeg)'''&lt;br /&gt;
:Das in den Weiten des WWWs wohl verbreitetste Format ist für Texturen generell eher weniger zu empfehlen, und für 2D-Objekte erst recht nicht. Zum einen ist die in diesem Format genutzte Kompression verlustbehaftet (also verlieren unsere Texturen an Qualität) und außerdem hat dieses Format keine Möglichkeit Transparenzinformationen zu speichern. Diese benötigt man aber für 2D-Objekte, denn im Normalfall wollen wir den Hintergrund des Objektes ja durchsichtig machen (dazu gleich mehr). Also sollte dieses Format nur verwendet werden wenn wir etwas darstellen wollen das sehr viele Details enthält (dann fällt die verlustbehaftete Kompression nicht so stark auf) und keine transparenten Bereiche enthält.&lt;br /&gt;
&lt;br /&gt;
*'''Graphical Interchange Format (*.gif)'''&lt;br /&gt;
:Direkt aus der Steinzeit des IT-Sektors kommt das (im Netz noch weit verbreitet) GIF-Format. Für unsere Zwecke ist es total unbrauchbar. Es ist eine Palettenformat, das maximal 256 verschiedene Farben unterstützt, allerdings inklusive Transparenzinformationen. Aber die maximal 256 Farben und die kaum vorhandene Kompression machen es für unseren Zweck nutzlos. Die Tatsache dass es Animationen unterstützt ist zwar im Internet für kleine animierte Sachen ganz toll, aber hilft uns auch nicht, denn dazu überwiegen die Nachteile zu stark&lt;br /&gt;
&lt;br /&gt;
*'''Portable Network Graphic (*.png)'''&lt;br /&gt;
:Der Nachfolger des GIF-Formates. Eigentlich auch sehr gut für Texturen geeignet, denn neben einem Alphakanal (maximal 8 Bit) und 8 Bit pro Farbkanal unterstützt es auch verlustfreie Kompression (mit einem recht hohen Kompressionsfaktor). Nachteil ist allerdings der Aufbau des Formates, denn der Chunkaufbau macht das Laden recht schwer und bisher gibt es nur Loader die eine DLL-Datei mit sich schleppen. Alternativ kann man auf neuen Betriebssystemen jedoch via GDI+ auch PNG-Dateien direkt laden.&lt;br /&gt;
&lt;br /&gt;
*'''TARGA (*.tga)'''&lt;br /&gt;
:Dieses Format werden sicherlich nicht viele Einsteiger kennen, allerdings ist dies '''''das perfekte Format für unsere Bedürfnisse bzw. Texturen im Allgemeinen'''''. Es kann nämlich bis zu 8 Bit pro Farbkanal (also das was man heute als 32-Bit Farbtiefe bezeichnet) speichern (= 24 Bit für Farben) und dazu noch einen Alphakanal (maximal 8 Bit). Der Alphakanal ist sehr nützlich, denn in ihm kann man die Transparenzinformationen eines Bildes ablegen. Auch viele kommerzielle Titel nutzen dieses Format (u.&amp;amp;nbsp;a. Quake3), und das aus gutem Grund. Kompression wird auch unterstützt, und zwar verlustfrei in Form einer LZW-Kompression. Alles in allem ist das momentan das geeignetste Format für Texturen, zumal so gut wie jedes Bildbearbeitungsprogramm damit umgehen kann. Nebenbei ist dies Format auch recht einfach aufgebaut und damit auch recht leicht einzulesen.&lt;br /&gt;
&lt;br /&gt;
*'''BITMAP (*.bmp)'''&lt;br /&gt;
:Das BMP-Format dürfte sicherlich jedem ein Begriff sein, ist aber genauso wie GIF ein Relikt aus der Steinzeit. Es kann zwar genauso wie das TGA-Format neben den 8 Bits pro Farbkanal auch einen maximal 8 Bits großen Alphakanal anbieten, allerdings kommen damit nur recht wenige Bildbearbeitungprogramme klar. Ausserdem sind die Bilddaten hier im BGR-Format abgelegt, statt dem eher üblichem RGB-Format (Red, Green, Blue). Das ist zwar sehr leicht umzuwandeln, bzw. kann mit passender GL-Konstante auch direkt übergeben werden, aber trotzdem ist dieses Format in keinem Falle dem TARGA-Format vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
*'''[[DDS|DirectDraw Surface (*.dds)]]'''&lt;br /&gt;
:Ein sehr neues Format, das den Ursprung (wie am Namen zu erkennen) in Microsofts DirectX-Schnittstelle hat. Es ist ein recht modernes Format, das speziell für die Speicherung von Texturen entwickelt wurde. Allerdings ist das eher was für Fortgeschrittene, denn weder das Laden dieses Formates ist einfach, noch seine Speicherung (selbst teure Bildbearbeitungsprogramme brauchen ein passendes Plugin für DDS und bei der Erstellung des Formates muss man auf bestimmte Sachen achten). Aber ich wollte es hier trotzdem mal erwähnt haben, damit man sieht das es auch spezielle Formate für Texturen gibt, und wenn ihr euch eingearbeitet habt, dann könnt ihr im Forum mehr zu dem Format finden (Mars hat dort auch einen grundlegenden Loader gepostet), denn es ist recht interessant. Es unterstützt feste Kompressionsratios, Mip-Maps, 3D-Texturen, uvm. '''Für fortgeschrittene 3D-Programmierer sollte DDS also das Format der Wahl sein''', denn es wurde als einziges der verbreiteten Bildformate speziell für diesen Bereich konzipiert. Vor allem die Tatsache dass die Kompression dieses Formates von den Grafikkarten direkt unterstützt wird prädestiniert es für diesen Anwendungsfall. So spart man sowohl beim Hochladen als auch beim Rendern viel Busbandbreite, da die GPU die Textur auch intern komprimiert behandelt und spart logischerweise auch VRAM. Man darf sich allerdings nicht vom Platzverbrauch der eigentlichen Datei irrtieren lassen, denn das Kompressionsformat ist fest (z.B. 4:1, 6:1, etc.) statt variable wie u.A. bei JPGs. Aber dafür entspricht dann die Dateigröße exakt der Größe die auch im VRAM belegt wird. Allerdings sollte man hier genau wissen was man tut, da es sehr viele Foramte innerhalb des DDS geben kann (DXT1, DXT3, DXT5, Palette, Fließkomma, etc.) und es durchaus Texturen gibt die durch den festen Kompressionsratio schlecht aussehen können. Ein gutes Beispiel ist hier ein blauer Himmel mit Sonne und Wolken, der durch einen weichen Farbverlauf gekennzeichnet ist. Da bei DXT1/3/5 fest komprimiert wird kann dort die Bildqualität sehr stark leiden. Dann sollte man im DDS unkomprimiert ablegen. Ausserdem gibt es inzwischen auch einen recht brauchbaren Loader für DDS in Delphi, und Lossys [[glBitmap]] kann dieses Format auch laden.&lt;br /&gt;
&lt;br /&gt;
Die obige Liste dürfte also einen recht (groben) Überblick über die verbreiteten Bildformate geben, und für dieses Tutorial begnügen wir uns erstmal mit dem TARGA-Format. Das wurde übrigens bereits 1984 erfunden, ist aber trotzdem noch nicht veraltet, sorgt aber dafür das so ziemlich jedes Programm damit umgehen kann.&lt;br /&gt;
&lt;br /&gt;
Wer sich übrigens nicht auf einen fremden Texturenloader verlassen möchte, sondern sich selbst um das Einlesen der Bildformate kümmern will, der sollte mal eine Blick auf [http://www.wotsit.org wotsig.org] werfen, einer recht großen Bibliothek die es sich zur Aufgabe gemacht hat Spezifikationen für Dateiformate zu sammeln. Dort wird man zu jedem der oben gennannten Bildformate eine solche Spezifikation finden, anhand derer man dann selbst Laderoutinen schreiben kann.&lt;br /&gt;
&lt;br /&gt;
===Textur laden===&lt;br /&gt;
&lt;br /&gt;
Auch wenn es ein sehr simples Unterfangen ist eine Textur zu laden, werde ich hier trotzdem nochmal kurz darauf eingehen. Das Tutorial richtet sich ja an Einsteiger, und von daher kann es nicht schaden auch mal kurz zu zeigen wie man so eine Textur lädt. Nutzen tun wir dazu die ''Textures.pas'' (die im Original von Jan Horn stammt. Ein weitere guter Loader ist [[Glbitmap_loader|glBitmap.pas]]), die sich im Download des Beispiels für dieses Tutorial befindet. Der Loader kann JPG, BMP und TGA laden. Außerdem lädt er auch den Alphakanal aus einer TGA-Textur.&lt;br /&gt;
&lt;br /&gt;
Bevor wir die Textur laden können, benötigen wir eine Variable in der wir den Bezeichner der Textur speichern. OpenGL erstellt für alle Ressourcen eindeutige Bezeichner (Bezeichner hier in Form eines Integerwertes, also einer eindeutigen ID), so auch für Texturen. Dieser Bezeichner ist vom Typ glUInt (U=unsinged Int=Integer, also vorzeichenloser Ganzzahlwert, was in Delphi dem Variablentyp ''Cardinal'' entpricht). Deshalb deklarieren wir unseren Texturenbezeichner auch so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var&lt;br /&gt;
 MyTex : glUInt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn wir mehrere Texturen laden und verwalten wollen, bietet sich natürlich ein (dynamisches) ''array of glUInt'' an, aber das sind Delphigrundlagen die in diesem Tutorial nichts zu suchen haben.&lt;br /&gt;
&lt;br /&gt;
Das Laden der Textur geht nun dank der ''Textures.pas'' ganz einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;LoadTexture('MeineTextur.tga', MyTex, False);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Parameter sollten recht logisch sein, der erste gibt den Dateinamen der Textur an, der zweite das Texturobjekt (in das die ID der Textur geschrieben wird) und der letzte Parameter gibt an ob die Textur aus einer dem Programm angehängten Ressource geladen werden soll. Sollte der Ladevorgang erfolgreich gewesen sein, so müsste sich in ''MyTex'' ein Wert &amp;gt; 0 befinden, nämlich der eindeutige Bezeichner dieses Texturenobjektes.&lt;br /&gt;
&lt;br /&gt;
===Textur anwenden===&lt;br /&gt;
&lt;br /&gt;
Wer sich schonmal ein wenig über OpenGL schlau gemacht hat, der wird wissen dass die GL eine Statemachine ist. Das trifft auch auf Texturen zu, denn wenn eine Textur gebunden wurde, wird sie solange auf alle Primitiven angewendet, bis entweder eine andere Textur gebunden wurde oder das Texturemapping über [[glDisable]] abgeschaltet wird. Das hat besonders dann den Vorteil, wenn man viele Objekte mit der gleichen Textur rendern muss, denn Texturenwechsel sind recht kostspielig. Von daher sollte man also bei vielen Objekten eine Sortierung nach Textur vornehmen, dann diese Textur binden und danach dann alle Objekte die diese Textur besitzen rendern.&lt;br /&gt;
&lt;br /&gt;
Doch bevor Texturen überhaupt angezeigt werden, müssen wir OpenGL erstmal mitteilen das es diese auch anzeigen soll. Dazu gibt es die Funktion '''glEnable''', der man mit der Konstante '''GL_TEXTURE_2D''' mitteilt das wir die 2D-Texturierung aktivieren wollen (1D oder 3D-Texturen benötigen wir ja in diesem Tutorial nicht):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_TEXTURE_2D);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unglaublich einfach, oder? So schnell kann das dank einer gut durchdachten API wie OpenGL gehen. Jetzt wo wir der API erstmal gesagt haben dass wir gerne Texturen sehen möchten, müssen wir auch noch sagen welche Textur als nächstes auf unserer Primitiven gezeigt werden soll. Dazu bindet (~ aktiviert) man das passende Texturobjekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D, MyTex);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von nun an werden alle folgenden Primitiven solange mit der hinter ''MyTex'' abgelegten Textur gerendert, bis das Texturemapping entweder deaktiviert wird oder wir eine andere Textur binden.&lt;br /&gt;
&lt;br /&gt;
===Transparenz===&lt;br /&gt;
&lt;br /&gt;
Eine wichtige Sache die es noch zu klären gibt ist Transparenz. Oben habe ich ja gesagt das wir unsere Objekte auf Quads kleben (über eine Textur), aber unsere vorgefertigten Objekte nur selten auch genau die Form eines Quads haben. Der Panzer auf der oben gezeigten Textur wird z.&amp;amp;nbsp;B. von sehr viel schwarz umgeben, das wir da natürlich nicht sehen wollen. Aber auch um die Transparenz brauchen wir uns unter OpenGL keine Sorgen zu machen, denn dafür gibt es den sog. Alphakanal der Textur, der angibt welche Teile einer Textur später transparent (oder besser gesagt gar nicht, aber dazu gleich mehr) gezeigt werden sollen. Aus diesem Grund haben wir uns mit dem TGA-Format auch ein Format gewählt das diesen Kanal direkt im Bild speichern kann, sodass wir diesen nicht extra erstellen oder aus einer seperaten Bilddatei laden müssen.&lt;br /&gt;
&lt;br /&gt;
Wie man den Alphakanal nun in die Textur bekommt hängt davon ab wie man seine Textur erstellt. Wer seine Objekte von Hand malt, der muss den Alphakanal im Bildbearbeitungsprogramm selbst erstellen. Wer seine Objekte allerdings vorrendert, der kann diese Arbeit im Normalfall von der 3D-Software erledigen lassen, die Alphainformationen direkt mitexportieren kann. Als kleiner Hinweis sei übrigens gesagt das man beim Rendering des Objektes im 3D-Programm die Kantenglättung deaktivieren muss, da man sonst an den Rändern Artefakte hat (die logischerweise Teile der Hintergrundfarbe enthalten) die dann in der OpenGL-Anwendung zu unschönen Effekten führen. Um das zu verbildlichen hier nochmal unsere Panzertextur, allerdings begleitet vom (im Bildformat gespeichertem) Alphakanal:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_5.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links also unsere Textur und rechts der Alphakanal. Den sieht man normalerweise nicht, aber fast jedes Bildbearbeitungsprogramm gibt einem die Möglichkeit sich diesen anzeigen zu lassen. Wie zu sehen befinden sich in unserem Falle nur zwei Werte im Alphakanal. Und zwar Schwarz (= 0) für komplett transparent und Weiß (= 1) für komplett Sichtbar.&lt;br /&gt;
&lt;br /&gt;
Unter OpenGL nutzen wir jetzt für die Transparenz den [[GlAlphaFunc|Alphatest]]. Transparenz ließe sich auch über Blending realisieren, allerdings hat Blending den Nachteil das man dann die transparenten Objekte nach Tiefe sortieren müsste, da Blending im Framepuffer abläuft und nicht wie der Alphatest auf Fragmentbasis, wo wir uns dann keine Sorge um die Reihenfolge unserer Objekte machen müssen. Wollen wir nun also den Alphakanal der Textur nutzen (natürlich muss dieser vorher im Texturenloader geladen werden, sonst geht's nicht) müssen wir vor dem rendern des mit der Objekttextur belegten Quads den Alphatest aktiveren und festlegen wie der Test auszusehen hat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_ALPHA_TEST);&lt;br /&gt;
glAlphaFunc(GL_GREATER, 0.1);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst aktiveren wir also den Alphaest (dazu gibt es die Konstante '''GL_ALPHA_TEST'''), bevor wir dann der GL mittels [[GlAlphaFunc|glAphaFunc]] sagen wie der Test aussehen soll. Der erste Parameter ('''GL_GREATER''') gibt an, das nur Fragmente (also Teile der Textur) gerendert werden sollen deren Alphawert größer ist als der im zweiten Wert angegebene (0.1). Wie auch Farbwerte wird der Alphawert unter OpenGL &amp;quot;geclampt&amp;quot;, also in eine bestimmte Reichweite gebracht, nämlich 0 (= Schwarz) bis 1 (= Weiß). Die 0,1 (statt der 0) als Vergleichswert nehmen wir quasi aus Toleranz. Wenn wir das obige also getan haben, dürften wir auf unserem Quad (sofern der Alphakanal korrekt erstellt und geladen wurde) also nur noch das eigentliche Objekt sehen, und der Hintergrund müsste an den transparenten (Alpha &amp;lt;= 0,1) zu sehen sein:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_6.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir unsere Bohne ohne aktiven Alphatest, was zur Folge hat das der eigentlich transparente (schwarze) Teil der Objekttextur den Hintergrund überdeckt. Rechts wuede der Alphatest aktiviert und wir sehen nur den Teil unseres Objektes den wir auch sehen wollen.&lt;br /&gt;
&lt;br /&gt;
===Das Objekt anzeigen===&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun unsere Textur mit passendem Alphakanal geladen haben und den Alphatest auch aktiviert haben, müssen wir schlussendlich noch unser(e) Objekt(e) rendern. Wie schon mehrfach gesagt nutzen wir dazu die GL_QUADS-Primitive. Bei diesem Primitiventyp beschreiben wir mit vier Eckpunkten ein Rechteck (das von der Grafikkarte dann in zwei Dreiecke zerlegt wird), wobei jeder Eckpunkt auch eine Texturkoordinate zugewiesen bekommt. Diese Koordinate gibt an, aus welchem Teil der Textur dieser Eckpunkt seine Bilddaten beziehen soll, und sie wird über das gesamte Quad hinweg interpoliert. Also haben wir in der genauen Mitte des Quads als interpolierte Texturkoordinate das genaue Mittel der übergebenen Texturkoordinaten. Um diese Interpolation müssen wir uns allerdings keine Sorgen machen, das macht die Grafikkarte.&lt;br /&gt;
&lt;br /&gt;
Und in Sachen Texturkoordinaten sind wir auch schnell fertig, denn für den Anfang haben wir pro Textur immer nur ein Objekt (später zeige ich dann wie man mehrere Objekt in eine Textur packt) und müssen dementsprechend auch nur eine 1 (= Ende der Textur) bzw. 0 (= Anfang der Textur vergeben. Wenn man sich das bildlich vorstellt, sieht das dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_7.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Da wir nur mit 2D-Texturen arbeiten, müssen wir pro Eckpunkt auch nur zwei Koordinaten angeben. Und zwar einmal in X-Richtung auf der Textur (unter OpenGL auch S-Richtung genannt, oft auch mit &amp;quot;U&amp;quot; betitelt) und in Y-Richtung (unter OpenGL T-Richtung, oft auch &amp;quot;V&amp;quot; genannt). Wenn S=0 und T=0, bedeutet das also das dieser Eckpunkt seinen [[Texel|Texel]] (wie Pixel, bloß im Bezug auf Texturen) aus der oberen linken Ecke unserer Textur (X=0/Y=0) bezieht, während S=1 und T=1 dafür sorgt das der Eckpunkt sich den Texel in der untersten rechten Ecke der Textur schnappt. Wie bereits oben erwähnt müssen wir uns um den Raum zwischen den vier Eckpunkten nicht kümmern, das wird ja von der Hardware linear interpoliert.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode zu obigem Beispiel sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBegin(GL_QUADS);&lt;br /&gt;
 glTexCoord2f(0,0); glVertex3f(-Breite/2, -Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(1,0); glVertex3f(+Breite/2, -Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(1,1); glVertex3f(+Breite/2, +Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(0,1); glVertex3f(-Breite/2, +Höhe/2, -Tiefe);&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer obigen Text aufmerksam gelesen hat, sollte eigentlich problemlos verstehen was der Quellcode denn bewirkt. Wer damit Problem hat, der sollte sich das obige Kapitel nochmal unbedingt sorgfältig durchlesen, denn das ist eine sehr wichtige Sache.&lt;br /&gt;
&lt;br /&gt;
Soviel also zu den Grundlagen von 2D unter OpenGL. Wer nämlich hier angelangt ist, sollte zumindest 2D-Objekte unter OpenGL anzeigen können. Evtl. ist es hier angebracht das Tutorial einige Minuten ruhen zu lassen und ein wenig mit dem Erlerntem herumzuprobieren. Danach geht's nämlich mit etwas fortgeschritteneren (aus Sicht des Einsteigers) Themen weiter.&lt;br /&gt;
&lt;br /&gt;
===Die Rolle des Tiefenpuffers===&lt;br /&gt;
&lt;br /&gt;
Trotz der Tatsache dass wir in 2D die dritte Dimension vernachlässigen, bedeutet dies nicht das wir den Tiefenpuffer nicht doch nutzen können. Und zwar nutzen wir diesen in 2D zur hardwarebeschleunigten Sortierung unserer Objekte. In 2D-Anwendungen kann es ja genauso vorkommen das ein Objekt unter (&amp;quot;hinter&amp;quot;) einem anderen liegt und da wäre es ziemlich dumm diese selbst zu sortieren, wo OpenGL uns doch einen Tiefenpuffer anbietet der dies für uns macht.&lt;br /&gt;
&lt;br /&gt;
Genau deshalb haben wir mittels glOrtho auch die Reichweite für unseren Tiefenpuffer angegeben. Haben wir dann auch noch den Tiefentest mittels {{INLINE_CODE|glEnable(GL_DEPTH_TEST)}} und dem passenden Tiefentest via {{INLINE_CODE|[[glDepthFunc]](GL_LESS ''oder'' GL_EQUAL)}} aktiviert, so können wir über die Z-Koordinate unserer Objekte angeben wo die nun genau liegen. Ein Objekt dessen Z-Koordinate also näher an Z-Near ist, wird dann über einem an gleicher Stelle befindlichem Objekt mit einer Z-Koordinate näher an Z-Far gerendert, und zwar egal welches dieser Objekte wir als erstes an die GL übergeben haben.&lt;br /&gt;
&lt;br /&gt;
===Backface Culling===&lt;br /&gt;
&lt;br /&gt;
Auch diese von OpenGL angebotene Funktionalität sollte hier nicht verschwiegen werden. Denn in OpenGL bestehen Flächen immer aus einer Vorder- und Rückseite (wie im echten Leben, ein Blatt Papier hat ja auch zwei Seiten, egal wie dünn es ist), was spätestens dann Sinn macht wenn man bedenkt das man sich in einer 3D-Umgebung ja komplett frei bewegen kann. Doch in unserer 2D-Welt sehen wir immer nur eine Seite unserer Objekte, egal was wir anstellen. Und genau deshalb sollten wir OpenGLs [[Backface Culling]] (zu Deutsch heisst das wörtlich &amp;quot;Rückseiten Ausschluß&amp;quot;, aber solche Fachbegriffe deutsch man auch besser nicht ein) aktivieren, denn ist dies nicht der Fall, so werden alle Berechnungen immer für beide Seiten eines Polygons ausgeführt. Und dabei spielt es keine Rolle welche der Seiten sichtbar ist oder nicht. Wir aktivieren also das Backfaceculling und sagen OpenGL dass die Rückseiten der Primitiven nicht dargestellt werden soll (letzteres könnte man sich sparen, da das die Voreinstellung ist, allerdings sollte man lieber auf Nummer sicher gehen):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_CULL_FACE);&lt;br /&gt;
glCullFace(GL_BACK);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solltet ihr jetzt übrigens eure Objekte nicht mehr sehen, dann habt ihr die Eckpunkte eurer Primitiven in der falschen Reihenfolge (Standard ist für OpenGL '''GL_CCW''' ('''C'''ounter'''C'''lock'''W'''ise, gegen den Uhrzeigersinn) angegeben. Ich empfehle dann entweder einen Blick ins Reedbook oder in eine der Beispielanwendungen, wo es eine Funktion namens ''DrawQuad'' gibt, die ein korrektes Quad rendert. Bei modernen Grafikkarten sollte das Backface Culling zwar nur recht wenig Performance bringen, aber es wäre trotzdem Performanceverschwendung dieses nette Feature einfach ungenutzt zu lassen.&lt;br /&gt;
&lt;br /&gt;
==Animation==&lt;br /&gt;
Bisher können wir zwar unsere 2D-Objekte mittels texturierter Quads auf dem Bildschirm darstellen, aber das ist natürlich noch recht statisch; und was wäre ein Computerspiel ohne Animationen? Und genau darum kümmern wir uns jetzt. Aber zuerst kurz zum Unterschied &amp;quot;Animation in 3D&amp;quot; und &amp;quot;Animation in 2D&amp;quot;. In 3D ist es normalerweise so, dass man ein 3D-Modell lädt und dann die einzelnen Teile des Modells animiert, sei dies über die GL-Befehle oder Animationsdaten im 3D-Format (Bones, Keyframes). Das bedeutet also das man in 3D quasi unendlich viele Freiheiten hat, denn man kann ja z.&amp;amp;nbsp;B. den Turm eines Panzers über [[glRotate]]f in jeden beliebigen Winkel bringen. In 2D ist das anders, denn da sind ja alle Grafiken vorgefertigt und werden nur abwechselnd auf unsere Quads geklebt. Würden wir dort also den Turm eines vorgefertigten Panzers rotieren lassen wollen, so müssten wir jeden Animationsframe vorfertigen und als Textur laden. Man muss sich also vorher Gedanken drüber machen ob 2D denn im Endeffekt wirklich weniger Aufwand bedeutet. Aber diese Entscheidung muss jeder für sich selbst fällen, weshalb wir uns nun zwei verschiedenen Animationsmöglichkeiten widmen werden.&lt;br /&gt;
&lt;br /&gt;
===Animation über Einzeltexturen===&lt;br /&gt;
''(Projektdatei : openGL2D_demo1)''&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_8.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Die wohl offensichtlichste (und auch einfachste) Art ein 2D-Objekt über Texturen zu animieren, ist über in einzelnen Texturen abgelegte Frames. Besonders aus einem 3D-Animationsprogramm (3D Studio, Maya) geht das besonders einfach. Denn diese Programme können eine Animation als Einzelbilder auf die Platte rendern. Dadurch hat man dann für eine Animation mit 60 Bildern 60 Texturen die dann einfach in ein Array geladen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var&lt;br /&gt;
 Frame : array of glUInt;&lt;br /&gt;
&lt;br /&gt;
SetLength(Frame, NumFrames);&lt;br /&gt;
for i := 0 to NumFrames-1 do&lt;br /&gt;
 LoadTexture('animframe'+IntToStr(i)+'.tga', Frame[i], False);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das zu animierende Objekt verpasst man dabei mit einem Fließkommawert der den aktuell anzuzeigenden Frame darstellt, und erhöht diesen dann über die Zeit. Beim Rendern des Objektes nutzt man diesen Wert gerundeten (Indizes müssen ja Ganzzahlwerte sein) als Index in das Texturenarray:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D,Frame[Round(CurrentFrame)]);&lt;br /&gt;
...&lt;br /&gt;
CurrentFrame := CurrentFrame + 0.025 * TimeFactor;&lt;br /&gt;
if CurrentFrame &amp;gt; Length(Frame) then&lt;br /&gt;
 CurrentFrame := 0;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieser Methode ist das man diese Animationen direkt aus seinem 3D-Programm heraus speichern kann und das die Animationen quasi unendlich lange (wobei sowohl Speicherplatz als auch Speicherausbau der Grafikkarte hier limitierende Faktoren sind) sein können. Nachteil ist der hohe Speicherverbrauch, sowohl auf der Platte als auch im Grafikspeicher, sowie die Tatsache das man dann recht oft die Textur wechseln muss.&lt;br /&gt;
&lt;br /&gt;
===Animation in einer einzigen Textur===&lt;br /&gt;
''(Projektdatei: openGL2D_demo2)''&lt;br /&gt;
&lt;br /&gt;
Diese Art der Animation ist wie oben schon angedeutet recht speichersparend und vermindert auch die Zahl der Texturenwechsel. Allerdings ist sie auch aufwendiger zu implementieren und unterliegt einigen Einschränkungen die man bei der Erstellung der Animationstextur berücksichtigen sollte. Statt also jeden Frame der Animation in einer eigenen Datei (und damit später auch Textur, obwohl sich das natürlich auch kombinieren lässt) abzulegen, wird versucht bei dieser Animationsart alle Frames in einem Gitter auf einer Textur anzuordnen.&lt;br /&gt;
&lt;br /&gt;
Wenn man nicht noch mit der Erstellung komplexer Texturkoordinaten rumfuchteln will, dann sollte man drauf achten dass das gewählte Gitter so hoch wie breit ist und die Texturen an diesem Gitter ausgerichtet sind. So habe ich bei dieser Beispieltextur (bevor sie für das Tutorial etwas verkleinert wurde) die Frames in einem Raster von 256x256 Pixeln untergebracht.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Explosion_det.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Zu sehen sind hier alle Animationsframes einer Explosionstextur aus der Beispielanwendung. Diese wurd mit einem entsprechenden Tool generiert, aber kaum ein 3D-Porgramm kann Animationen direkt in eine einzelne Textur exportieren. Hier muss man sich dann mit passenden Plug-Ins oder Drittprogrammen aushelfen.&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Abspielen&amp;quot; dieser Animation ist nun recht einfach, denn wir erinnern uns ja daran das die Texturkoordinaten in OpenGL immer im Bereich 0 bis 1 liegen, unabhängig (es gibt Ausnahmen, aber interessiert hier nicht) von der Größe unserer Textur. Also müssen wir im Endeffekt nur wissen wie viele Spalten und Zeilen unsere Animationstextur enthält um für jeden Frame die passenden Texturkoordinaten errechnen zu können. Um es konkret zu machen nehmen wir obiges Beispiel. Es besteht aus drei Reihen und drei Spalten, wobei die Animationen von links nach rechts durchlaufen. Also bedeutet dies das unser erster Animationsframe bei S=0 / T=0 beginnt und bei S=1/4 / T=1/4 Ende, Frame 2 beginnt dann bei S=1/4 / T=0 und endet bei S=2/3 / T=1/4, usw. Dies zu errechnen sollte als keine Probleme bereiten, genauso wie das Rendern.&lt;br /&gt;
&lt;br /&gt;
Doch dürfen wir die Nachteile dieser Animationsart auch nicht verschweigen. Das es oft schwierig ist (wenn man die Objekte und Animationen sowieso von Hand zeichnet dann natürlich nicht) aus den Animationsframes eine einzelne Textur zu machen habe ich bereits gesagt, aber man muss auch wie immer auf die Hardwarelimitationen achten. Denn wenn man viele Animationen in einer Textur unterbringen will, wird diese oft recht groß und selbst auf modernen Karten sollte die Textur nicht größer als 2048x2048 Pixel sein. Wenn wir also ein Objekt der Größe 256x256 haben, bekommen wir im besten Falle (2048 wird auf älteren Karten entweder nicht machbar sein, deren Grafikkartenspeicher fast ganz aufbrauchen, oder zu langsam sein) 64 Animationsframes auf eine Textur. Alles darüber müsste man dann in eine weitere Textur auslagern, was den Verwaltungsaufwand stark erhöhen würde. Ausserdem muss man drauf achten, dass sich die Animationsframes nicht direkt berühren, also das zwischen einem sichtbarer Objektteil in Frame N mindestens ein Pixel Abstand zum sichtbaren Objektteil in Frame N+1 besteht. Denn dadurch das die Textur von OpenGL gefiltert wird, verlaufen Pixel die direkt aneinander liegen ineinander; wodurch dann unschöne Effekte entstehen. Ein weitere (allerdings nicht so gravierender) Nachteil ist die Tatsache dass man solche Animationen nicht über Texturenwiederholung mehrfach auf ein Objekt legen kann. Wenn man bei der erstgenannten Animationsart z.&amp;amp;nbsp;B. statt S=1/T=1 S=2/T=2 nutzt, dann wird dann Animation insgesamt viermal auf dem Quad wiederholt. Da man hier aber über die Texturkoordinaten quasi einen Frame aus der Textur herauspickt ist das nicht möglich, was im Normalfall aber kaum Gewicht haben sollte.&lt;br /&gt;
&lt;br /&gt;
===Rotation und Skalierung===&lt;br /&gt;
''(Projektdatei: openGL2D_demo3)''&lt;br /&gt;
&lt;br /&gt;
Wenn man alles selbst zeichnet (also z.&amp;amp;nbsp;B. mit der GDI arbeitet), dann hat man für die Rotation (oder Skalierung) eines Objektes im Normalfall nur zwei Möglichkeiten: Entweder man schreibt sich eigene Routinen die den Pixelsalat rotieren (was meist langsam ist, solange man es nicht in Assembler schreibt) oder man erstellt Bilddateien auf denen die Objekte schon vorrotiert sind. Erstere Methode ist wie gesagt langsam und sieht hässlich aus (es sei denn man filtert auch noch selbst) und die zweite Methode schränkt einen auf die vorberechneten Drehwinkel ein.&lt;br /&gt;
&lt;br /&gt;
Alle gerade genannten Probleme kann man unter OpenGL dank der hardwarebeschleunigung ad acta legen. Nicht nur dass man dank Hardware unendlich schnell rotieren kann, diese Rotation auch noch frei ist, nein, man bekommt sogar das Filtering dank Hardware umsonst:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_10.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links ist das um 15° gegenüber dem Ausgangsbild gedrehte Raumschiff ohne Filtering zu sehen. Gut ist hier die dadurch entstehende &amp;quot;Körnung&amp;quot; erkennbar, die in Bewegung noch sehr viel unschöner aussieht. Rechts sieht man das gleiche, diesmal allerdings mit Filtering. Der Unterschied dürfte direkt auffallen, und besonders auf hellen Hintergründen ist er noch frapierender. Natürlich sollte man die Grundlagen von OpenGL beherrschen um die Rotation korrekt anwenden zu können, denn folgender Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glRotatef(45, 0,0,1);&lt;br /&gt;
glTranslatef(320, 240, 0);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bewirkt etwas total anderes als folgender Code :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glTranslatef(320, 240, 0);&lt;br /&gt;
glRotatef(45, 0,0,1);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer sich die OpenGL-Grundlagen bereits angeeignet hat, der wird sicher schnell erkannt haben wo der Unterschied liegt. Denn in OpenGL bewegt man Objekte nicht direkt, sondern immer nur den Ursprung der Matrix. Ersterer Code rotiert also unsere Matrix um 45° und verschiebt diese dann um 320 Einheiten auf der X- und 240 auf der Y-Achse, was dazu führt das unser Objekt in einem recht großen Kreis um den Ursprung rotiert wird. Der zweite Codeschnippsel hingegen verschiebt unser Objekt an den Punkt 320/240 (in unserem Falle genau die Bildschirmmitte) und rotiert dann dort unser Objekt um die eigene Achse. Das ist auch der Rotationscode den wir im Normalfall nutzen um ein Objekt um sich selbst rotieren zu lassen. In unserer 2D-Anwendung müssen wir auch prinzipiell nur um die Z-Achse rotieren, denn die ragt in OpenGL &amp;quot;in&amp;quot; den Bildschirm hinein. Um das nachzuvollziehen einfach mal den rechten Arm grade ausstrecken und &amp;quot;um&amp;quot; den ausgestreckten Zeigefinger rotieren lassen. Euer Arm stellt dann in diesem Falle die Z-Achse dar.&lt;br /&gt;
&lt;br /&gt;
Das Skalieren eines Objektes gestaltet sich noch leichter, denn hier muss man nichts weiter machen als vor dem Rendern des Quads ein glScalef aufzurufen und diesem dann den Skalierungsfaktor (1=keine Skalierung) pro Achse zu übergeben. Da wir hier allerdings nur in 2D arbeiten sollten wir die Z-Skalierung immer bei 1 belassen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glScalef(2,2,1);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obiger Quellcode zeichnet unser Objekt in der doppelten Größe (also statt 256x256 Einheiten 512x512 Einheiten groß). Über die Skalierung kann man schön in 2D einen Tiefeneffekt realisieren, zum Beispiel ein Raumschiff das mit einer Skalierung von 0,5 /0,5 / 1 auf einem Träger startet und dann zu Beginn des Levels langsam in Richtung 1 / 1 / 1 skaliert wird. Dadurch wird das Schiff größer und es entsteht beim Betrachter der Eindruck, das Schiff würde hinaufsteigen.&lt;br /&gt;
&lt;br /&gt;
==Scrollen und zoomen==&lt;br /&gt;
''(Projektdatei: openGL2D_demo4)''&lt;br /&gt;
&lt;br /&gt;
Selbst viele kommerzielle 3D-Spiele benötigen oft einen 2D-Teil um solche Sachen wie Übersichtskarten (man will ja gerne wissen wo man hin will) oder evtl. Credits und ähnliche größere 2D-Anzeigen zu tätigen, die oft den ganzen Bildschirm einnehmen oder gar größer sind. Besonders bei solchen Sachen wie z.&amp;amp;nbsp;B. einer großen Übersichtskarte (sei es nun die Strategiekarte für einen Schlachtplatz im Zweiten Weltkrieg, oder die Übersichtskarte eines Fantasyreiches) sind die Vorteile von OpenGL (wie an dem im Download enthaltenem Beispiel zu erkennen) gut ersichtlich. Das Scrollen wird durch einen einfachen Aufruf an [[glTranslate]]f erledigt (um die außerhalb des sichtbaren Bereichs liegenden Teile der Karte muss man sich dabei keine Sorgen machen), während man das vergrößern der Karte (~ zoomen) mit einem einfachem [[glScale]]f vollbringen kann.&lt;br /&gt;
&lt;br /&gt;
Und dank der Hardwarebeschleunigung wird diese Karte schneller angezeigt als man dies von Hand (oder über andere 2D-APIs je tun) könnte. Auf einer halbwegs modernen Grafikkarte sollten locker an die 1000 FpS drin sein.&lt;br /&gt;
&lt;br /&gt;
Nachdem man die Übersichtskarte geladen hat, gestaltet sich das Rendern selbiger als sehr einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D, MapTex);&lt;br /&gt;
glTranslatef(MapPos.x, MapPos.y, 0);&lt;br /&gt;
glScalef(MapScale, MapScale, MapScale);&lt;br /&gt;
DrawQuad(0,0,0, MapSize.x,MapSize.y);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht schockierend einfach aus. Mehr braucht es nicht um eine Übersichtskarte zu scrollen und zu zoomen. Allerdings sollte man wie bereits einige Male erwähnt wurde auf die Hardwarelimiationen achten. Wenn die Übersichtskarte also allzu groß sein sollte, dann kann man diese ja ohne Probleme unterteilen und als mehrere Quads rendern. Außer der etwas abgeänderten Positionierung der einzelnen Kartenteile ändert sich aber am Grundprinzip nichts.&lt;br /&gt;
&lt;br /&gt;
==Tiling (Kachelung)==&lt;br /&gt;
''(Projektdatei: openGL2D_demo5)''&lt;br /&gt;
&lt;br /&gt;
Die oben genannte Technik mag zwar gut genug für statische Übersichtskarten sein, aber wenn man eine dynamische Karte aus der Vogelperspektive realisieren will, so kommt man mit einer riesigen vorgefertigten Textur nicht weit. Dafür gibt es dann aber eine Technik namens &amp;quot;Tiling&amp;quot;, was zu Deutsch so viel wie &amp;quot;Kachelung&amp;quot; heißt. Hier hat man ähnlich einem Schachbrett ein zweidimensionales Spielfeld das aus unterschiedlichen Kacheln besteht die als Texturen vorliegen. In einem zweidimensionalem Array wird dann für jedes Feld gespeichert welche Textur zu ihm gehört. Diese Technik ist immer noch recht weit verbreitet (zumindest im Hobbybereich) und für 2D-Spiele aus der Vogelperspektive recht gut geeignet, wobei hier der Großteil der Arbeit eher beim Grafiker als beim Programmierer liegt, denn da die Teils nur Vierecke darstellen müssen Übergänge von z.&amp;amp;nbsp;B. einem Terraintyp zum anderen in die Textur gezeichnet werden. &lt;br /&gt;
&lt;br /&gt;
Das Rendern eines solchen Spielfeldes gestaltet sich dabei sehr einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;for x := 0 to MapWidth-1 do&lt;br /&gt;
 for y := 0 to MapHeight-1 do&lt;br /&gt;
  begin&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, MapTexture[Map[x,y]]);&lt;br /&gt;
  DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
  end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Allerdings ist obige Methode alles andere als optimiert. Das erste (und größte) Problem ist die Tatsache das unabhängig von aktuellen Betrachtungsposition immer die komplette Karte gerendert wird. Bei großen Karten (z.&amp;amp;nbsp;B. 128x128 Kacheln) gehen dann selbst moderne Karten in die Knie. Die Kacheln außerhalb des Sichtbereiches werden zwar von der Grafikkarte nicht gerendert (da sie außerhalb des Viewports liegen), aber müssen dennoch in jedem Frame über den Bus gesendet werden, genauso wie die Texturenwechsel in jedem Frame stattfinden müssen. Das erste Problem lässt sich recht schnell lösen, in dem wir einfach prüfen ob die aktuell zu rendernde Kachel auch im momentan sichtbarem Bereich liegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glScalef(MapScale, MapScale, MapScale);&lt;br /&gt;
for x := 0 to High(Map) do&lt;br /&gt;
 for y := 0 to High(Map[x]) do&lt;br /&gt;
  if (MapPos.x + x*32 &amp;gt;= -16*MapScale) and (MapPos.x + x*32 &amp;lt;= SizeX/MapScale+16) and&lt;br /&gt;
     (MapPos.y + y*32 &amp;gt;= -16*MapScale) and (MapPos.y + y*32 &amp;lt;= SizeY/MapScale+16) then&lt;br /&gt;
      begin&lt;br /&gt;
      glBindTexture(GL_TEXTURE_2D, MapTex[Map[x,y]]);&lt;br /&gt;
      DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
      end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der If-Abfrage, die wir vor dem Rendern einer jeden Kachel machen, prüfen wir jetzt ganz einfach ob die aktuelle Kachel im Sichtfeld liegt. Da wir eine dynamische Karte haben und die Vorteile von OpenGL nutzen wollen, müssen wir bei dieser Abfrage natürlich auch den Zoomfaktor (''MapScale'') und das Scrolling (''MapPos'') mit einbeziehen.&lt;br /&gt;
&lt;br /&gt;
Dank dieser offensichtlichen Optimierung dürften wir jetzt einen starken Performancegewinn von mehreren hundert Prozent sehen, denn sehr viele Texturenwechsel fallen weg und es wird sehr viel weniger Geometrie über den Bus gesendet. Aber natürlich sind wir noch nicht am Ende der Fahnenstange angelangt, denn wie gesagt sind Texturenwechsel recht performancelastig. Also liegt es nahe diese zu optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;for t := 0 to High(MapTex) do&lt;br /&gt;
 begin&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, MapTex[t]);&lt;br /&gt;
 for x := 0 to High(Map) do&lt;br /&gt;
  for y := 0 to High(Map[x]) do&lt;br /&gt;
   if Map[x,y] = t then&lt;br /&gt;
    if (MapPos.x + x*32 &amp;gt;= -16*MapScale) and (MapPos.x + x*32 &amp;lt;= SizeX/MapScale+16) and&lt;br /&gt;
       (MapPos.y + y*32 &amp;gt;= -16*MapScale) and (MapPos.y + y*32 &amp;lt;= SizeY/MapScale+16) then&lt;br /&gt;
        DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen haben wir unsere Schleife etwas umgebaut. Wir gehen jetzt in der Hauptschleife durch alle unsere Kacheln (abgelegt in ''MapTex'') und dann für jede Kachel die komplette Karte in beide Dimensionen durch. So binden wir jede Texur nur einmal und rendern dann alle Kacheln die diese Textur nutzen. Das klingt erstmal so (zumindest vom Schleifenaufbau her) als würden wir hier Performance vernichten, denn schliesslich gehen wir jetzt nicht einmal die komplette Karte durch, sondern so viele Male wie wir Kacheltexturen haben. Allerdings ist es meistens so das der CPU-Overhead durch die zusätzlichen Schleifendurchläuft weniger kostet als uns die gesparten Texturenwechsel eingebracht haben. Im Normalfall (es gibt natürlich Situationen wo der CPU-Overhead zu groß wird, z.&amp;amp;nbsp;B. bei wirklich riesigen Karten) sollten wir auch durch diese Optimierung einen Performancezuwachs im zweistelligen Prozentbereich erkennen.&lt;br /&gt;
&lt;br /&gt;
So viel also zum Thema Kachelung. Besonders für kleinere Projekte ist diese Technik ein guter Start und vor allem ist diese Technik leicht umzusetzen. Ist natürlich nicht mehr zeitgemäß, aber bei den meisten Hobbyprojekten geht es ja eher um den Inhalt und nicht nur um das Äußere. &lt;br /&gt;
&lt;br /&gt;
==Spezialeffekte==&lt;br /&gt;
&lt;br /&gt;
Nach diesem langen Marsch sind wir jetzt so ziemlich mit allen im 2D-Bereich verwendeten Techniken durch und können uns nun einem interessanterem Kapitel zuwenden; den Spezialeffekten. Hier ist der eigenen Kreativität natürlich keine (oder kaum, je nach Hardware) Grenze gesetzt, weshalb ich nur einige häufig unter 2D genutzte Effekte erwähnen möchte.&lt;br /&gt;
&lt;br /&gt;
===Beleuchtung (&amp;quot;Per-Pixel&amp;quot;)===&lt;br /&gt;
''(Projektdatei: openGL2D_demo6)''&lt;br /&gt;
&lt;br /&gt;
Beleuchtung ist ja (auch wenn man das nicht so wahrnimmt, da es ja im echten Leben selbstverständlich ist) eine Sache die man in keinem Spiel vernachlässigen sollte. Ohne korrekte Beleuchtung geht viel Atmosphäre flöten, aber besonders in einer 3D-Umgebung ist korrektes Per-Pixel-Licht (die OpenGL-Beleuchtung arbeitet auf Vertexbasis) oft schwer zu implementieren (was dank Shader aber leichter geworden ist). In einer 2D-Umgebung ist das aber zum Glück sehr viel einfacher, denn dort haben wir z.&amp;amp;nbsp;B. im Falle einer 2D-Karte ja keine dritte Dimension um die wir uns kümmern müssten, müssen unsere Lichtquellen also nicht auf die Szene draufprojizieren.&lt;br /&gt;
&lt;br /&gt;
In 2D geht das also ganz einfach und wir machen die Beleuchtung bequem über eine Lichttextur in der die Intensität der Lichtquelle abgelegt ist. Für die Demo habe ich dazu einen einfachen radialen Verlauf gewählt, aber der Fantasie sind da keine Grenzen gesetzt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_12.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Farbinformationen speichern wir nicht in der Textur, denn wir wollen ja dynamisch bleiben und realisieren die Färbung des Lichtes später in unserem Programm über einen [[glColor]]3f  Aufruf. Bevor wir allerdings loslegen, sollten noch ein paar Kleinigkeiten im Bezug auf diese (einfache Form der) Beleuchtung geklärt werden. Damit wir unsere Szene mit einer solchen Textur &amp;quot;beleuchten&amp;quot; können, nutzen wir additives Blending. Das bedeutet also das wir zur Farbe im Framepuffer (der unsere Karte zeigt) den Farbwert in unserer Lichttextur addieren. Dort wo unsere Textur also komplett weiß ist, haben wir auf der Karte die volle Lichtfarbe. Blending hat aber einen Nachteil, der in 3D oft sehr viel Kopfzerbrechen macht, aber in 2D leicht gelöst werden kann: Blending arbeitet &amp;quot;auf&amp;quot; dem Framepuffer, was also bedeutet das OpenGL in diesem Falle nicht für uns sortiert. Wenn wir dann also eine Lichttextur rendern die nahe am Betrachter ist und dahinter (im Raum) eine zweite Lichttextur rendern die weiter entfernt ist, werden wir diese nicht sehen, da im Framepuffer bereits die erste Lichttextur &amp;quot;liegt&amp;quot; (sprich dort der Z-Wert der ersten Textur abgelegt wurde und die Fragmente der zweiten Textur deshalb aufgrund des Z-Tests verworfen werden). Das ist natürlich nicht korrekt, aber in 2D lässt sich dieses Problem mit dem passenden Tiefentest lösen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glDepthFunc(GL_ALWAYS);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte man diese Tiefenfunktion erst setzen bevor man die Lichtquellen zeichnet, sofern man vorher den Tiefenpuffer nutzen will um die Objekte auf seiner Karte in der Höhe zu sortieren. Denn wie der Name vermuten lässt bewirkt diese Form des Tiefentests das Fragmente (=&amp;quot;Pixel auf Probe&amp;quot;) immer rasterisiert werden, egal ob sie jetzt durch ein bereits im Frampuffer liegendes Fragment verdeckt werden würden oder nicht. Wenn wir mit diesem Tiefentest nun also zwei Lichtquellen übereinander rendern würden, werden diese korrekt angezeigt. Aber wie immer soll euch dieser etwas technisch klingende Text nicht aus dem Konzept bringen, weshalb ich dann hier folgende zwei Bilder reden lasse:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_13.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir zwei sich überlappende Lichtquellen mit einem normalerweise verwendetem Tiefentest ('''GL_LEQUAL''' oder '''GL_LESS'''). Dass die grüne Lichtquelle die zweite verdeckt ist reiner Zufall und liegt wohl daran das diese als erstes gerendert wurde. Wie oben gesagt (vereinfacht) steht dann im Z-Puffer drin das an dieser Stelle (des grünen Lichtes) bereits ein Objekt im Z-Puffer liegt. Danach wird dann irgendwann die zweite (blaue) Lichtquelle gerendert, aber die Stellen an denen bereits steht dass dort im Z-Puffer ein Fragment liegt werden nicht mehr gerendert, aufgrund des Tiefentests. Das zweite Bild ist hingegen korrekt, einzig der Tiefentest wurde auf '''GL_ALWAYS''' umgestellt. Dann werden die mit der Lichttextur belegten Quads immer gezeichnet, egal ob sich an der Z-Position bereits ein Fragment befindet oder nicht, und bei Lichtquellen ist das reichlich egal welche zuerst gerendert wird. Denn ob ich jetzt Blau mit Grün addiere, oder Grün mit Blau ist egal, denn beides ergibt im Ende Türkis. Das dürfte dann hoffentlich verstanden worden sein, wenn nicht dann einfach mal das Beispielprogramm öffnen und den Tiefetest wie hier angesprochen ändern; Probieren geht je bekannter weise meist über Studieren.&lt;br /&gt;
&lt;br /&gt;
Abschließend auch noch kurz zum verwendeten Blendmodus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBlendFunc(GL_ONE, GL_ONE);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer sich schon mal ein wenig mit dem Thema Blending beschäftigt hat, wird schnell erkennen was hier abläuft. Sowohl der Quellfaktor als auch der Zielfaktor stehen auf '''GL_ONE''', was bedeutet dass bei unserer Blendoperation die bereits im Framepuffer befindliche Farbe mit der Farbe unseres Lichtes addiert wird (additives Blending genannt). Bei einer grünen Lichtquelle haben wir in der Mitte also RGB = 0/1/0 und wenn wir das dann auf einen Pixel legen würden der halb grau ist (RGB = 0,5/0,5/0,5) hätten wir als Ergebnis RGB = 0,5/1/0,5 (1+0,5 ist eigentlich 1,5 , aber OpenGL zwängt Farbwerte in den Bereich 0..1).&lt;br /&gt;
&lt;br /&gt;
===Texturenverläufe===&lt;br /&gt;
''(Projektdatei: openGL2D_demo7)''&lt;br /&gt;
&lt;br /&gt;
Im Kapitel &amp;quot;Kachelung&amp;quot; habe ich erwähnt, dass es eigentlich Aufgabe des Grafikers ist die Überläufe zwischen zwei unterschiedlichen Kacheln zu erstellen. Allerdings lässt sich das auch mit OpenGL bewerkstelligen, und zwar dank Blending und des Alphakanals. Dazu rendern wir zuerst ein Quad mit der ersten Kachel, und zwar dort wo diese Kachel komplett erscheinen soll mit vollem Alpha (vierter Parameter von [[glColor]]4f = 1) und dort wo später die andere Kachel komplett erscheinen soll mit Alpha = 0. Danach rendern wir an exakt der gleichen Stelle die zweite Kachel, müssen aber natürlich darauf achten das wir den richtigen Tiefentest aktiviert haben damit diese auch sichtbar ist ('''GL_ALWAYS''' oder '''GL_LEQUAL'''), allerdings mit genau umgekehrten Alphawerten und aktiviertem Blending. Fürs Blending nutzen wir als Quellfaktor '''GL_SRC_ALPHA''' und als Zielfaktor dann in logischer Konsequenz '''GL_DST_ALPHA'''. Dadurch wird dann im finalen Ergebnis dort wo die erste Kachel eine Alpha von 1 hat ihr kompletter Farbwert übernommen und dort wo die zweite Kachel einen Alpha von 1 hat deren voller Farbwert. Dazwischen wird in gewohnter Weise interpoliert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glDisable(GL_BLEND);&lt;br /&gt;
glBindTexture(GL_TEXTURE_2D, TileA);&lt;br /&gt;
glBegin(gl_Quads);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(0,0); glVertex3f(-128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(1,0); glVertex3f( 128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(1,1); glvertex3f( 128,  128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(0,1); glvertex3f(-128,  128, 0);&lt;br /&gt;
glEnd;&lt;br /&gt;
&lt;br /&gt;
glEnable(GL_BLEND);&lt;br /&gt;
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);&lt;br /&gt;
glBindTexture(GL_TEXTURE_2D, TileB);&lt;br /&gt;
glBegin(gl_Quads);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(0,0); glVertex3f(-128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(1,0); glVertex3f( 128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(1,1); glVertex3f( 128,  128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(0,1); glVertex3f(-128,  128, 0);&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Allerdings wird das bei komplexeren Kachelübergängen recht aufwendig und endet in jeder Menge Overdraw, da man dann viele Übergänge rendern muss. Aber wer sich mal näher damit beschäftigen will, sollte einen Blick auf das &amp;quot;Verblendet&amp;quot;-Tutorial (Einsteiger) von Phobeus werfen, in dem auch diese Technik hier näher besprochen wird.&lt;br /&gt;
&lt;br /&gt;
===Schatten===&lt;br /&gt;
''(Projektdatei : openGL2D_demo8)''&lt;br /&gt;
&lt;br /&gt;
Im 3D-Bereich sind Schatten eigentlich immer noch die &amp;quot;Königsdisziplin&amp;quot; für jeden Programmierer, besonders wenn diese volumetrisch und vor allem auch korrekt sein sollen. Meist muss man dazu die Szene analysieren, Umrisse von 3D-Objekten generieren und auch noch diverse Spezialfälle beachten (Stichwort &amp;quot;Betrachter im Schattenvolumen&amp;quot;). In unserer heilen 2D-Welt geht das aber schon wie bei der Beleuchtung sehr viel einfacher und hat mit dreidimensionalen Schatten rein gar nichts gemeinsam.&lt;br /&gt;
&lt;br /&gt;
Hier gehen wir nämlich ganz einfach hin und täuschen Schatten vor indem wir unser Objekt (das dazu natürlich einen Alphakanal besitzen muss) mittels {{INLINE_CODE|glColor3f(0, 0, 0)}} schwarz machen und dann unter dem eigentlichen Objekt leicht versetzt (die Richtung des Versatzes kann man je nach Lichteinfall verändern) rendern. Über [[glScalef]] passen wir dann noch die Größe des Schattens an um einfach vermitteln zu können wie hoch sich unser Objekt befindet. Wenn wir also den Schatten eines Spielers rendern, dann kann der genauso groß sein wie der Spieler selbst, aber bei einem Flugzeug das hoch über dem Boden fliegt sollte der Schatten schon etwas verkleinert werden um einen Eindruck von der Flughöhe zu vermitteln.&lt;br /&gt;
&lt;br /&gt;
Rein programmiertechnisch sind Schatten in 2D (auch wenn diese keineswegs physikalisch korrekt sind) also genau das Gegenteil von 3D-Schatten: Einfach und ohne jegliche Hindernisse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glPushMatrix;&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, ShipTex);&lt;br /&gt;
 glEnable(GL_ALPHA_TEST);&lt;br /&gt;
 glAlphaFunc(GL_GREATER, 0.1);&lt;br /&gt;
 glScalef(0.75, 0.75, 0.75);&lt;br /&gt;
 glColor3f(0, 0, 0);&lt;br /&gt;
 DrawQuad(60,-60,1, 256,192);&lt;br /&gt;
glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
glPushMatrix;&lt;br /&gt;
 glColor3f(1, 1, 1);&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, ShipTex);&lt;br /&gt;
 glEnable(GL_ALPHA_TEST);&lt;br /&gt;
 glAlphaFunc(GL_GREATER, 0.1);&lt;br /&gt;
 DrawQuad(0,0,0, 256,192);&lt;br /&gt;
glPopMatrix;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ersten Block rendern wir unser Objekt etwas verkleinert und nach unten/rechts versetzt, natürlich komplett schwarz. Danach müssen wir nur noch unser Objekt drüberrendern (in gewohnter Weise) und fertig ist unser Schatten:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_14.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
==Schlusswort==&lt;br /&gt;
&lt;br /&gt;
Das war es also zum Thema 2D in OpenGL. Ich hoffe stark das dieser doch recht ausführliche Bericht so ziemlich alle Bereiche abgedeckt hat und damit auch häufig gestellte Fragen beantwortet. Natürlich war das nicht alles was in diesem Bereich machbar ist, allerdings kann ich hier schlecht auf jeden Effekt eingehen, denn sonst könnte ich das Tutorial gleich als ein einige hundert Seiten starkes Buch verkaufen.&lt;br /&gt;
&lt;br /&gt;
Doch eines sei noch am Schluss gesagt: 2D ist zwar programmiertechnisch fast immer (besonders bei in 3D komplexen Sachen wie Beleuchtung und Schatten) sehr viel einfacher und man kommt dann auch meist schneller ans Ziel, allerdings ist hier die Erstellung des Inhalts meist aufwendiger. Während z.&amp;amp;nbsp;B. ein 3D-Terrain zwar von der Programmierung her aufwendiger ist, muss man dort am Ende nur eine Terraintextur draufkleben und fertig ist die Sache. In 2D muss man dies hingegen über Kacheln lösen und dann für jeden Übergang verschiedene Kacheln in einem Bildbearbeitungsprogramm erstellen. Oder zum Beispiel das in unserem letzten Beispiel verwendete Raumschiff; wenn man das in 3D über ein 3D-Modell animiert (Keyframes), dann ist es kaum Aufwand was am Modell zu verändern (andere Textur, Form ändern), aber in 2D liegen diese Animationen vorberechnet auf der Platte, und sobald man dann was am Raumschiff ändert, müssen auch alle Animationen geändert werden.&lt;br /&gt;
&lt;br /&gt;
Wie so oft im Leben muss man also abwägen was jetzt für die eigene Anwendung richtig ist. Essentiell reicht es sich die Frage ''&amp;quot;Ist es für mich aufwendiger in die 3D-Programmierung einzusteigen, oder es ist es aufwendiger den Content für meine 2D-Anwendung zu erstellen&amp;quot;'' zu beantworten, aber das kann ich euch nicht abnehmen, da müsst ihr selbst drauf antworten können. Außerdem sei noch gesagt das die moderne Generation der Computerspieler inzwischen 3D gewohnt ist, was dazu führt das 2D-Anwendungen dann spielerisch sehr überzeugen müssen.&lt;br /&gt;
&lt;br /&gt;
In dem Sinne also viel Spaß in der zweiten Dimension (die auch Spaß machen) kann. Und vergesst nicht: Ich WILL Feedback zu diesem Tutorial und außerdem will das DGL-Team sehen was ihr so mit unseren Tutorials auf die Beine stellt. Wenn dabei also was halbwegs brauchbares raus gekommen ist, lasst es uns wissen!&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:'''Sascha Willems''' (webmaster AT delphigl.de)&lt;br /&gt;
&lt;br /&gt;
== Dateien ==&lt;br /&gt;
* {{ArchivLink|file=tut_opengl2d_vcl|text=Delphi-VCL-Quelltexte und Windows-Binaries zum Tutorial}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|[[Tutorial Lektion 8]]|[[Tutorial_Matrix2]]}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorial|2D]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=24583</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=24583"/>
				<updated>2010-01-12T17:56:16Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* unterstütze Formate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glBitmap - Texturenloader =&lt;br /&gt;
&lt;br /&gt;
== Warum das Ganze und wo kann ich sie finden? ==&lt;br /&gt;
&lt;br /&gt;
Früher benutzte ich die glBMP, da sie so &amp;quot;schön&amp;quot; Objekt orientiert war. Leider hatte mein Grafiktreiber zu der Zeit einen Fehler bei der Auswahl des Texturformates. So führte es dazu, dass sobald ich eine Textur mit Alphakanal und dem Standard Texturformat an OpenGL übergab, er als Farbtiefe 16 Bit verwendete. Wenn ich ein Foto genommen hätte wäre mir das wahrscheinlich gar nicht aufgefallen aber dummerweise (oder glücklicherweise) hatte ich aber eine Textur mit einem weichem Farbverlauf. Wie zu erwarten war sah das natürlich alles ziemlich schrecklich aus. Bis dahin kann der Loader ja nichts dafür wenn in einem Treiber ein Fehler existiert. Nur das kuriose an dem Ganzen war, dass meine Textur in Wirklichkeit gar keinen Alphakanal haben durfte. Also habe ich mich auf die Suche nach der Ursache gemacht und bin auch prompt fündig geworden. Der Loader war der Meinung er müsse alle Texturen mit einem Alphakanal versehen ungeachtet der Tatsache ob sie nun einen hatten oder eben nicht. Das ist natürlich eine Sache mit der ich mich nicht abfinden wollte. Kurz darauf begann ich also eine Ableitung der glBMP Texturenklasse zu erstellen und dort musste ich mit Schrecken feststellen, dass die Rechte in der Klasse so ungünstig vergeben wurden, dass ich keine andere Wahl gehabt hätte als direkt die Unit zu editieren. Da ich ungern externe Quellen editiere habe ich für mich die andere Alternative entschieden. Was dabei rausgekommen ist sieht man ja jetzt.&lt;br /&gt;
&lt;br /&gt;
Gefunden werden kann sie entweder im DGL-SDK oder auf der [http://www.dev-center.de/index.php?cat=header&amp;amp;file=glbitmap Webseite] von [[Benutzer:Lossy eX|Lossy eX]].&lt;br /&gt;
&lt;br /&gt;
== Allgemeines und Features ==&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel geht nicht darauf ein was zu tun ist um in OpenGL eine Textur darstellen zu können. In ihm werde ich lediglich darauf eingehen was man tun kann und muss um mittels der glBitmap eine Textur laden zu können. Außerdem werden die verfügbaren Einstellungen und ihre Wirkungen erklärt. Für alles andere wäre es besser das [[Tutorial_lektion4|Tutorial über Texturen]] durchzulesen.&lt;br /&gt;
&lt;br /&gt;
Der wichtigste Unterschied zu den bestehenden Loadern bringe ich gleich einmal als erstes. Die glBitmap legt die Texturen anders im Speicher ab. Um zwar im speziellen meine ich damit die 2D Texturen. Bei bestehenden Loadern werden diese Texturen mit der untersten Zeile zu erst im Speicher abgelegt. In der glBitmap werden sie aber mit '''der obersten Zeile zu erst abgelegt'''. Man könnte auch sagen, dass sie bei den bestehenden Loadern auf dem Kopf stehen. Beide Möglichkeiten funktionieren und sind korrekt. Das Einzige was sich in diesem Zusammenhang ändert ist die [[glTexCoord| Adressierung der Texturen]]. Sie müssen entsprechend geändert werden. Sollte das nicht möglich sein so besteht mit der Methode ''FlipVert'' die Möglichkeit die Textur zu spiegeln. Näheres in Abschnitt [[Glbitmap_loader#Texturen_konfigurieren|Texturen konfigurieren]]. Im Normalfall sollte das andere Verhalten nicht zu Problemen führen sondern die Arbeit damit vereinfachen und verständlicher gestalten.&lt;br /&gt;
&lt;br /&gt;
Die glBitmap holt sich ihre Daten ausschließlich aus Streams. Das zugrundeliegende Format wird automatisch anhand des Inhaltes der Daten ausgewählt. Es besteht also kein Notwendigkeit daran, dass der Entwickler wissen muss um welches Format es sich in Wirklichkeit handelt.&lt;br /&gt;
&lt;br /&gt;
=== unterstütze Formate ===&lt;br /&gt;
&lt;br /&gt;
* Windows Bitmaps (*.bmp) Wird Automatisch auf 24 Bit gesetzt sollte es kleiner sein.&lt;br /&gt;
* JPEG (*.jpg)&lt;br /&gt;
* TARGA (*.tga) komprimiert und unkomprimiert, 24 und 32 Bit. Ursprung unten links oder oben links&lt;br /&gt;
* Portable Network Graphics (*.png) 24 Bit mit oder ohne Alphakanal. Es wird eine zusätzliche Bibliothek benötigt.&lt;br /&gt;
* [[DDS|Direct Draw Surfaces]] (*.dds) 8,16,24,32 Bit DXT1,DXT3,DXT5, keine Cubemaps, keine Mipmaps&lt;br /&gt;
Es besteht auch die Möglichkeit die Bilddaten dynamisch generieren zu lassen oder sie aus einer Instanz der Klasse TBitmap zu laden. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Um PNGs laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define ''pngimage'' hinzugefügt werden. Alternativ dazu kann das Define auch in der glBitmap auskommentiert werden.&lt;br /&gt;
&lt;br /&gt;
== Texturen laden ==&lt;br /&gt;
&lt;br /&gt;
Das Laden von Texturen kann auf 2 Weg geschehen. Bei Beiden ist aber zu beachten, dass '''OpenGL richtig initialisiert worden sein muss''' bevor man eine Textur erzeugen kann. Was noch sehr wichtig ist. Es sollte niemals eine Textur bei jedem Rendervorgang angelegt und freigegeben werden! Es ist viel effektiver, wenn man die Textur zu beginn lädt und so lange im Speicher behält bis sie nicht mehr benötigt wird. Wenn man sie erst später benötigt, dann kann man sie auch später noch nachladen aber auch dann sollte sie so lange wie nötig existieren.&lt;br /&gt;
&lt;br /&gt;
=== Procedural ===&lt;br /&gt;
&lt;br /&gt;
Hierbei genügt der Aufruf einer einzelnen Methode um eine Textur zu laden und diese an OpenGL zu übergeben. Allerdings auf Grund der Einfachheit steht nur das Laden aus Dateien oder Ressourcen zur Verfügung. Zusätzliche Funktionalität können dabei nicht benutzt werden. Generell empfehle ich immer die Objekt orientierte Variante.&lt;br /&gt;
 &lt;br /&gt;
 '''var'''&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 LoadTexture('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;myTex\Wall.bmp&amp;lt;/font&amp;gt;', Texture, False); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei ''Wall.bmp'' geladen und die TextureID wird in die Variable ''Texture'' geschrieben. Wenn die Textur dann benötigt wird, dann muss man diese entsprechend mit [[glBindTexture]] binden und das benötigte Texturtarget mit [[glEnable]] aktivieren. Das Target ist üblicherweise ''GL_TEXTURE_2D''. Wenn die Textur nicht mehr benötigt wird sollte sie mit [[glDeleteTextures]] auch wieder frei gegeben werden.&lt;br /&gt;
&lt;br /&gt;
=== Objekt orientiert ===&lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt beschäftigt sich ausschließlich mit den 2D Texturen. Aber grundsätzlich lässt sich alles hier erwähnte auch auf die 1D Texturen und die Cubemaps übertragen.&lt;br /&gt;
Der Objekt orientierte Weg erfordert zwar eine wenig mehr Schreibarbeit aber nur so kann man den vollen Funktionsumfang der glBitmap genießen.&lt;br /&gt;
&lt;br /&gt;
Als Erstes müssen wir eine Instanz der Texturenklasse definieren. Dies tun wir vorzugsweise als Member des Fensters auf dem wir zeichnen.&lt;br /&gt;
&lt;br /&gt;
 TForm1 = '''class'''(TForm)&lt;br /&gt;
   ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;''&lt;br /&gt;
 '''private'''&lt;br /&gt;
   fTexture: TglBitmap2D; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;''&lt;br /&gt;
 '''end;'''&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 '''procedure''' TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 '''begin'''&lt;br /&gt;
   ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;''&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;''&lt;br /&gt;
   fTexture.LoadFromFile('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;myTex\Wall.bmp&amp;lt;/font&amp;gt;'); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
   fTexture.GenTexture; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;'' &lt;br /&gt;
 '''end;'''&lt;br /&gt;
&lt;br /&gt;
Für Schreibfaule besteht auch noch die Möglichkeit in einem überladenen Konstruktor einem Dateinamen anzugeben.&lt;br /&gt;
&lt;br /&gt;
   fTexture := TglBitmap2D.Create('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;myTex\Wall.bmp&amp;lt;/font&amp;gt;'); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
   fTexture.GenTexture; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;'' &lt;br /&gt;
&lt;br /&gt;
In GenTexture wird im Normalfall immer überprüft ob die Textur eine gültige Größe hat. Sollte diese Überprüfung nicht gewünscht sein so kann man diese mit einem optionalen Parameter deaktivieren. Diese Überprüfung testet auch ob die Texturgröße eine Potenz von 2 ist (1, 2, 4, 8, 16 usw.) und wenn nicht ob solche Texturen von dem Rendercontex unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
   fTexture.GenTexture(False); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Es wird keine Prüfung der Texturgröße vorgenommen.&amp;lt;/font&amp;gt;'' &lt;br /&gt;
&lt;br /&gt;
Wenn kein Fehler aufgetreten ist und alles so funktioniert hat wie es sein sollte, dann kann die Textur benutzt werden. &lt;br /&gt;
&lt;br /&gt;
   fTexture.Bind; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Sollte es nicht gewünscht werden, dass auch gleichzeitig das Target aktiviert wird so muss Bind mit dem Parameter False aufgerufen werden. Damit wird nur noch die Textur gebunden.&lt;br /&gt;
&lt;br /&gt;
Sollte man die Textur einmal nicht mehr benutzen wollen so genügt es entweder eine andere Textur zu binden oder Unbind von der Texturenklasse aufzurufen. Damit wird die Textur mit der TexturID 0 gebunden und das Target deaktiviert. Auch hier existiert wieder der Parameter der es verhindert, dass das Target deaktiviert wird.&lt;br /&gt;
&lt;br /&gt;
Wenn die Anwendung beendet wird müssen wir auch hier unsere Textur wieder frei geben. Dies geschieht so.&lt;br /&gt;
&lt;br /&gt;
   fTexture.Free; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit '''vor dem Löschen des Rendercontex''' geschehen sollte, da so die Textur zu einem sinnvollem Zeitpunkt gelöscht werden kann. Wenn der Rendercontex nicht mehr existiert, so sollte die Textur auch nicht mehr existieren und wenn man dann noch einmal versucht sie zu löschen so könnte es zu Problemen führen. Bisher ist mir kein Fall bekannt aber ausschließen kann man es auch nicht. Also zu erst immer die Texturen frei geben und anschließend des Rendercontex löschen.&lt;br /&gt;
&lt;br /&gt;
== Das leidige Thema Alphakanal ==&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei Möglichkeiten einen Alphakanal in eine Textur zu integrieren. Der einfachste und schnellste Weg ist, wenn sich dieser Kanal von Beginn an in der Textur befindet. Dazu wird ein Grafikprogramm benötigt welches so etwas unterstützt und ein Dateiformat welches das Speichern eines Alphakanals ermöglicht. Ein solches Programm ist zum Beispiel [http://www.gimp.org/ Gimp]. Als mögliche Dateiformate kämen TGAs und PNGs in Frage. Alle anderen Formate unterstützen keinen Alphakanal. Sollte man sich für diesen Weg entscheiden so genügt es dann, ganz normal die Textur zu laden und zu benutzen und schon besitzen wir einen funktionierenden Alphakanal. Ich persönlich empfehle bis auf wenige Ausnahmen immer diesen Weg.&lt;br /&gt;
&lt;br /&gt;
Nichts desto trotz habe ich ja gesagt, dass es noch eine Möglichkeit gibt. Bei diesem Weg haben wir Alphakanal und RGB Daten in zwei getrennten Bildern vorliegen. Aber wie bekommen wir das jetzt in ein Bild? Dafür bietet die glBitmap die Möglichkeit einen Alphakanal aus einem separaten Bild zu laden. Zu Beginn benötigen wir jedoch wieder eine Instanz der Klasse und es müssen schon normale Bilddaten geladen worden sein. Und ganz Wichtig damit es überhaupt funktioniert. '''Der Aufruf muss vor ''GenTexture'' stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.'''&lt;br /&gt;
&lt;br /&gt;
 fTexture.AddAlphaFromFile('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;myTex\Wall_alpha.bmp&amp;lt;/font&amp;gt;'); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Das war alles nun sind wir im Besitz einer Textur mit einem Alphakanal. Es besteht unter anderem auch die Möglichkeit den Alphakanal aus verschiedenen anderen Quellen zu laden (Resourcen, Streams, TBitmap). Zusätzlich dazu kann man den Kanal aber auch dynamisch erstellen. Dafür existiert die Methode ''AddAlphaFromFunc''. Die Findigen unter euch habe aber bestimmt schon herausgefunden, dass man bei alle Methoden solch eine Function übergeben kann. Näheres dazu findet ihr im Abschnitt ''e = mc²''&lt;br /&gt;
&lt;br /&gt;
Etwas was häufiger gebraucht wird habe ich von Hause aus schon implementiert. Und zwar das Erstellen eines Alphakanals anhand einer Farbe. &lt;br /&gt;
&lt;br /&gt;
 fTexture.AddAlphaFromColorKey(Red, Green, Blue, Deviation); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Dabei wird nur auf vollkommen durchlässig und nicht durchlässig unterschieden. Alle Pixel die die angegebene Farbe besitzen werden dabei als 0 (nicht Sichtbar) in den Alphakanal geschrieben alle anderen erhalten 255 (Sichtbar). Die ''Deviation'' bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEGs ist das nicht unwichtig, da die Bilder beim Komprimieren leicht abgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
Damit die OpenGL Primitiven jetzt transparent dargestellt werden muss der [[GlAlphaFunc|Alphatest]] oder das [[glBlendFunc|Blending]] aktiviert sein. Sonst nützt einem der Alphakanal nicht sonderlich viel.&lt;br /&gt;
&lt;br /&gt;
Entfernen kann man einen Alphakanal natürlich auch. Dazu genügt der Aufruf von ''RemoveAlpha''. Dieser muss natürlich nicht mit der glBitmap erstellt worden sein. Er kann auch aus einer Datei geladen worden sein.&lt;br /&gt;
&lt;br /&gt;
 fTexture.RemoveAlpha; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
== Texturen konfigurieren ==&lt;br /&gt;
&lt;br /&gt;
Hier beginnt jetzt der Teil der für die Meisten recht wichtig sein dürfte. Bisher haben wir ja nur Daten geladen und diese an OpenGL übergeben. Nun wollen wir aber ein wenig an den Einstellungen rumschrauben und sehen was wir daraus machen können.&lt;br /&gt;
&lt;br /&gt;
Folgende Einstellungsmöglichkeiten verändern ausschließlich nur das Verhalten der glBitmap. Sie haben keinen Einfluss auf die resultierende Textur.&lt;br /&gt;
&lt;br /&gt;
'''''DeleteTextureOnFree''''' ist vom Typ Boolean und gibt an ob beim Freigeben der Klasse die Texture auch freigegeben wird oder ob weiter existieren darf. Standard wird sie mit freigegeben.&lt;br /&gt;
&lt;br /&gt;
'''''FreeDataAfterGenTexture''''' ist vom Typ Boolean und gibt an ob die Bilddaten nach dem Erzeugen der Textur aus dem Hauptspeicher entfernt werden sollen oder nicht. Im Normalfall werden sie das auch.&lt;br /&gt;
&lt;br /&gt;
'''''Target''''' ist vom Typ Cardinal und bestimmt das OpenGL Target. Wird von den Klassen auf den Standardwert gesetzt und muss nur dann auf einen anderen Wert gesetzt werden, wenn ein anderes Target verwendet werden soll. Zum Beispiel bei der Verwendung von Texture_rectangle. Es sollte aber immer direkt nach dem erstellen gesetzt werden, da die Textur sonst unbrauchbar gemacht werden könnte.&lt;br /&gt;
&lt;br /&gt;
'''''Format''''' ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|tfDefault&lt;br /&gt;
|Dabei wird das Standardformat des Grafikkartentreibers benutzt. Je nach eingestellter Qualität kann dies 16 oder 32 Bit sein.&amp;lt;/td&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|tf16Bit&lt;br /&gt;
|Hier wird die Textur in 16Bit abgelegt.&lt;br /&gt;
|-&lt;br /&gt;
|tf32Bit&lt;br /&gt;
|Hier wird die Textur in 32Bit abgelegt.&lt;br /&gt;
|-&lt;br /&gt;
|tfCompressed&lt;br /&gt;
|Bei diesem Format wird zu erst geschaut ob eines der folgenden Kriterien erfüllt ist. Extension GL_ARB_texture_compression, OpenGL Version 1.3 oder die Extension GL_EXT_texture_compression_s3tc. Sollten alle 3 Möglichkeiten nicht funktionieren so wird das Standardformat vom Grafikkartentreiber benutzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''''MipMap''''' ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|mmNone&lt;br /&gt;
|Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&lt;br /&gt;
|-&lt;br /&gt;
|mmMipmap&lt;br /&gt;
|Ähnlich wie bei komprimierten Texturen werden zu erst verschiedene neue Möglichkeiten überprüft. Ab OpenGL Version 1.4 oder mit der Extension GL_SGIS_generate_mipmap unterstützt die Grafikkarte ein generieren der [[Mipmaps]]. Das ist natürlich wesentlich schneller als der Weg ausschließlich über die Software. Sollte es keinen anderen Weg geben so werden die [[Mipmaps]] mittels der GLU generiert.&lt;br /&gt;
|-&lt;br /&gt;
|mmMipmapGlu&lt;br /&gt;
|In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden '''''SetFilter''''' und '''''SetWrap''''' können das Filterverhalten und das Beschränken der Texturkoordinaten angepasst werden. Eine genaue Auflistung möglicher Werte findet man beim Artikel zu [[glTexParameter]]. Das Aufrufen der Methoden ist überall dort möglich wo auch [[glTexParameter]] gültig ist. Mögliche Fehlerhafte Werte werden automatisch auf die vorhandene Textur angepasst. So wird bei SetFilter niemals ein [[MipMaps|MipMap]] bei die Filterung eingestellt wenn keine [[MipMaps]] erzeugt wurden. Das würde sonst dazu führen, dass die Textur nicht dargestellt werden könnte.&lt;br /&gt;
&lt;br /&gt;
'''''FlipVert''''' und '''''FlipHorz''''' sind Methoden die nichts anderes machen als das Bild entlang der entsprechenden Richtung (Vertikal und Horizontal) zu spiegeln. Dies wäre auch mit der Funktionsschnittstelle möglich aber besonders bei FlipVert wäre es unpraktisch da wir so nicht die komplette Zeile am Stück kopieren könnten, sondern nur Pixel für Pixel.&lt;br /&gt;
&lt;br /&gt;
Zum Invertieren des Bildes genügt es die Methode '''''Invert''''' aufzurufen. Sie bekommt zwei boolsche Parameter mit denen man steuern kann was man invertieren möchte. Einen für RGB und einen für den Alphakanal.&lt;br /&gt;
&lt;br /&gt;
Die Methode '''''ToNormalMap''''' wurde implementiert um aus einer 2D Textur eine NormalMap zu erzeugen. Er funktioniert ähnlich wie das NormalMapPlugin für Gimp. Die Methode bekommt 3 Parameter. Der Erste gibt an mit welcher Methode die Normalmap berechnet werden soll. Mögliche Werte hierfür sind&lt;br /&gt;
{|{{Prettytable}}&lt;br /&gt;
|nm4Samples&amp;lt;/td&amp;gt;&lt;br /&gt;
|Hierbei werden die jeweils geradlinigen benachbarten Pixel zu gleichen Teilen in die Berechnung einbezogen. (Oben, Unten Recht und Links). Diese Methode ist die einfachste, schnellste und empfindlichste gegenüber Farbvariationen.&lt;br /&gt;
|-&lt;br /&gt;
|nmSobel&lt;br /&gt;
|Mit dieser Methode werden fließen benachbarten Pixel zu gleichen Teilen in die Berechnung ein.&lt;br /&gt;
|-&lt;br /&gt;
|nm3x3&lt;br /&gt;
|Bei diese Methode fließen auch alle benachbarten Pixel in die Berechnung ein. Die diagonalen Pixel werden Doppelt gewertet. Die NormalMap wirkt so ruhiger und nicht so anfällig gegen kleine Farbveränderungen.&lt;br /&gt;
|-&lt;br /&gt;
|nm5x5&lt;br /&gt;
|Diese Methode benutzt eine Matrix von 5*5 Pixeln um Ihre Berechnungen durch zu führen. Je weiter die Punkte vom Mittelpunkt entfernt sind so geringer wird deren Einfluss.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der zweite Parameter gibt eine Skalierung an. Mögliche Werte hierfür liegen im Bereich von -100 bis 100. Bei einer Skalierung von 0 würde sich die Normalmap Wohlgefallen auflösen, da sie dann praktisch eine gerade Fläche darstellen würde. Die Textur dürfte dann außergewöhnlich gleichfarbig blau werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Mit dem dritten und letzten Parameter kann man die Berechnung der Normalmap von den RGB Werten auf den Alphakanal verschieben. Die Berechnung zieht sich dann nicht mehr die RGB Werte sondern den Alphakanal zu Rate. Der genaue Nutzen davon liegt zwar momentan selber vor mir verborgen aber wer weiß wozu man so etwas später noch gebrauchen kann. ;-)&lt;br /&gt;
&lt;br /&gt;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
Hierbei handelt es sich um eine Möglichkeit die Texturdaten zu manipulieren. Die Schnittstelle wurde so gestaltet, dass sie sehr flexibel und typisiert ist. Sprich, dass man immer genau weiß worum es sich handelt und welche Felder unterstützt werden. Eine einfache Handhabung und eine gute Ausführungsgeschwindigkeit waren natürlich auch sehr wichtige Punkte dabei. Finden kann man die Funktionsschnittstelle beim Hinzufügen des Alphakanals oder immer wenn man möchte durch die Methode ''AddFunc''. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen ''Invert'', ''AddAlphaFromColokey'', ''ToNormalMap'' und ''FillWithColor''. Die Klasse ''TglBitmapNormalMap'' generiert ihre Texturen zum Beispiel mit der Schnittstelle.&lt;br /&gt;
&lt;br /&gt;
Die Arbeitsweise der Funktionsschnittstelle ist recht einfach. Es wird nichts anderes gemacht als 1 Mal Zeile für Zeile den Pointer eines jeden Pixels an eine Funktion zu Übergeben und darauf zu vertrauen, dass sie das Richtige tut. Um die Ausführung zu Beschleunigen wird ausschließlich mit Pointern gearbeitet. Die Funktionen bekommen die Instanz des Objektes, die Größe, die Position, das Quellpixel, das Zielpixel und einen Pointer auf benutzerdefinierte Daten übergeben. Das ist natürlich eine ganze Menge Holz was da an Daten übergeben aber das ist alles notwendig um die gewünschte Flexibilität erreichen zu können.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir das ganze mal an einem Beispiel. Und zwar dem Aufruf von ''Invert''. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 '''if''' ((UseRGB) '''or''' (UseAlpha)) &lt;br /&gt;
   '''then''' AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha '''and''' HasAlpha) '''shl''' 1 '''or''' Integer(UseRGB)));&lt;br /&gt;
&lt;br /&gt;
In Zeile 1 handelt es sich lediglich um eine kleine Sicherheit. Es bringt ja nichts, wenn man eine Funktion ausführen möchte die keinen Nutzen hat. Zeile 2 Ruft die Methode ''AddFunc'' auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt ''AddFunc'' gesagt ob sie eine Kopie des Bildes erstellen soll. Für pixelübergreifende Funktionen ist dies unerlässlich, da man sich sonst seine noch benötigten Daten überschreiben würde. Der dritte Wert ist ein Pointer der zusätzliche Informationen hält. In diesem Falle handelt es sich lediglich um ein Bitset bei dem Bit 2 den Alphakanal und Bit 1 die RGB Werte repräsentiert. Es könnte sich dabei aber auch um einen Pointer auf ein Record handeln.&lt;br /&gt;
&lt;br /&gt;
 '''procedure''' glBitmapInvertFunc(Sender : TglBitmap; '''const''' Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   '''const''' Source, Dest: TglBitmapPixelData; '''const''' Data: Pointer);&lt;br /&gt;
 '''begin'''&lt;br /&gt;
   '''if''' (Integer(Data) '''and''' $1 &amp;gt; 0) '''then begin'''&lt;br /&gt;
     Dest.ptRed^   := '''not''' Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := '''not''' Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := '''not''' Dest.ptBlue^;&lt;br /&gt;
   '''end;'''&lt;br /&gt;
 &lt;br /&gt;
   '''if''' (Integer(Data) '''and''' $2 &amp;gt; 0) '''then begin'''&lt;br /&gt;
     Dest.ptAlpha^ := '''not''' Dest.ptAlpha^;&lt;br /&gt;
   '''end;'''&lt;br /&gt;
 '''end;'''&lt;br /&gt;
&lt;br /&gt;
'''''Position''''' und '''''Size''''' beinhalten die Aktuelle Position des Pixels und die Größe des Bildes. Das Record TglBitmapPixelPosition beinhält 4 Werte. Fields, X, Y, Z. Fields beschreibt welche Felder überhaupt zur Verfügung stehen. Mögliche Werte Dafür sind ffX, ffY und ffZ. Wofür X, Y und Z stehen erkläre ich jetzt mal nicht, dass sollte jedem klar sein. Bei einem 2D Bitmap sind üblicherweise die Felder X und Y mit leben gefüllt. Das Feld Z liegt brach.&lt;br /&gt;
&lt;br /&gt;
'''''Source''''' und '''''Dest''''' beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert ''Fields''. Mögliche Werte für ihn sind ffRed, ffGreen, ffBlue und ffAlpha. Diese Felder sind anders als bei bei Position keine richtigen Werte sondern Pointer die Direkt auf die Farbwerte in den Bildern zeigen. Es gibt deswegen ''Source'' und ''Dest'', da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind ''Source'' und ''Dest'' gleich. Bei hinzufügen eines Alphakanals bezieht sich ''Source'' auf die Pixeldaten im dem Quellbild und ''Dest'' wie gewohnt auf die Daten im Zielbild.&lt;br /&gt;
&lt;br /&gt;
In dem obigen Beispiel werden die Bits des Parameters Data ausgewertet und die entsprechenden Kanäle negiert. Der Komplexibilität sind kaum Grenzen gesetzt. Alle Wissensdurstigen unter euch sollten sich dann auch mal die Methode ''ToNormalMap'' anschauen. Dort werden zwei Funktionen aufgerufen. In der Ersten werden Daten gesammelt mit denen in der Zweiten die Normalmap berechnet wird. Oder auch die Klasse ''TglBitmapNormalMap''. In dieser wird eine generelle Berechnungsroutine aufgerufen. Diese bekommt aber für jede Fläche der Map eine andere interne Methode übergeben. Mit dieser werden dann die Werte für jedes Pixel gefüllt.&lt;br /&gt;
&lt;br /&gt;
Noch ein Wort für alle Geschwindigkeitsfanatiker. Ich hatte ein mal spaßeshalber die Methode ''FlipHorz'' nachgebaut und die Geschwindigkeit gemessen. Das Ergebnis hat mich selber sehr angenehm überrascht. Die Hardcodierte super optimierte Methode benötigte bei 300 Aufrufen, auf ein 512x512 Pixel großes Bild ca. 5 Sekunden. Die Methode mit dem Funktionsaufruf benötigte Lediglich 300 ms länger. Ich selber hätte eher mit dem Doppelten der Zeit gerechnet.&lt;br /&gt;
&lt;br /&gt;
== Cubemaps mit glBitmap ==&lt;br /&gt;
&lt;br /&gt;
Das einzige worin sich CubeMaps von 2D Texturen unterscheidet ist das Laden. Aber das ist auch nicht viel komplizierter als bei 2D Texturen. Die Handhabung mit den Texturen (Binden, Frei geben) ist wie bei 2D Texturen weswegen ich das auch nicht noch einmal extra wiederholen werde.&lt;br /&gt;
&lt;br /&gt;
=== Procedural ===&lt;br /&gt;
&lt;br /&gt;
Wie auch bei den 2D Texturen haben wir die Auswahl zwischen zwei möglichen Wegen. Der procedurale Weg unterscheidet sich lediglich in der Anzahl der angegebenen Texturen. Das sind diesmal natürlich ein paar mehr.&lt;br /&gt;
&lt;br /&gt;
 '''var'''&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
 LoadCubeMap('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;xpos.bmp&amp;lt;/font&amp;gt;', '&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;xneg.bmp&amp;lt;/font&amp;gt;', '&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;ypos.bmp&amp;lt;/font&amp;gt;', '&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;yneg.bmp&amp;lt;/font&amp;gt;', '&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;zpos.bmp&amp;lt;/font&amp;gt;', '&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;zneg.bmp&amp;lt;/font&amp;gt;', Texture, False);&lt;br /&gt;
&lt;br /&gt;
Die ersten 6 Parameter geben die jeweils 6 Texturen an. Die Namen der Parameter geben auch gleichzeitig deren Ziel an. Also immer schön auf die Reihenfolge achten. In dem Siebten wird die Textur ID geschrieben und der Achte gibt an ob aus Resourcen geladen werden soll oder nicht.&lt;br /&gt;
&lt;br /&gt;
=== Objekt orientiert ===&lt;br /&gt;
&lt;br /&gt;
Der Objekt orientierte Weg gestaltet sich dieses mal ein wenig schreibintensiver. Es müssen ja auch schließlich 6 Texturen geladen werden. Aber das kann man auch praktischerweise in eine Schleife packen. Das praktische daran ist, dass wir alles mit nur einer Klasseninstanz lösen können (und auch müssen).&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;''&lt;br /&gt;
 fCubeMap.LoadFromFile('&amp;lt;font color=&amp;quot;blue&amp;quot;&amp;gt;xpos.jpg&amp;lt;/font&amp;gt;'); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Die Textur wird normal angelegt und es wird wie gewöhnt ein Bild in den Speicher der Klasse geladen. Dieses Bild verhält sich wie jedes andere Bild. Es kann also wie gewöhnt manipuliert werden. Zum Beispiel durch die Funktionsschnittstelle.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap.GenerateCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir ''GenerateCubeMap'' mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Das müssen wir dann natürlich noch mit allen anderen Maps machen. '''''Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.''''' Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode ''GenTexture'' steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. '''''Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.'''''&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die Aktivierung der automatische Generation der Texturkoordinaten deaktivieren kann. Standard ist dieses eingeschalten. Ähnlich wie beim Binden einer Textur. Dort kann man verhindern, dass das Target aktiviert wird.&lt;br /&gt;
&lt;br /&gt;
== Normalmaps mit glBitmap ==&lt;br /&gt;
&lt;br /&gt;
NormalMaps sind nichts anderes als Spezielle Cubemaps. Sie dienen dazu um Per Pixel Normale auch auf Systemen ohne Shaderhardware zu ermöglichen. Benutzt werden kann das zum Beispiel bei Bumpmapping mit [[GL_ARB_texture_env_dot3]].&lt;br /&gt;
&lt;br /&gt;
=== Procedural ===&lt;br /&gt;
&lt;br /&gt;
Wie auch bei den 2D Texturen und Cubemaps haben wir die Auswahl zwischen zwei möglichen Wegen. Da diese Texturen dynamisch generiert werden fällt die Anzahl der Parameter ziemlich gering aus. Sie besteht lediglich aus einer Texturgröße. In diesem Falle haben die resultierenden Texturen eine Größe von 32x32 Pixeln. Der zweite Parameter ist ein altbekannter von uns. Er ermöglicht es uns eine TexturID zu empfangen. Auf die Handhabung mit dieser ID gehe ich nicht noch einmal ein, da das oberhalb schon oft genug besprochen wurde.&lt;br /&gt;
&lt;br /&gt;
 '''var'''&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;''&lt;br /&gt;
 LoadNormalMap(32, Texture);&lt;br /&gt;
&lt;br /&gt;
=== Objekt orientiert ===&lt;br /&gt;
&lt;br /&gt;
Dieser Weg ist etwa genau so schreibintensiv wie der Procedurale. Hierbei wird eine Normalmap erstellt bei der einzelnen Texturen eine Größe von 32x32 Pixeln haben.&lt;br /&gt;
&lt;br /&gt;
 fNormalMap := TglBitmapNormalMap.Create; ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;''&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); ''&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
Erstaunlich aber wahr. Das war bereits alles. Von nun an kann die Textur wie jede andere CubeMap auch verwendet werden.&lt;br /&gt;
&lt;br /&gt;
== Bekannte Probleme und Einschränkungen ==&lt;br /&gt;
&lt;br /&gt;
Vor einer Weile wurde im Forum die Frage gestellt warum die glBitmap beim Laden eines BMPs einen &amp;quot;Stream Read Error&amp;quot; produziert. Da das Bitmap nun mal ein sehr einfaches Format ist hat mich das auch sehr stark verwundert. Nach langem hin und her Rätseln kam ich dann dennoch darauf was das Problem war. Es lag daran, dass das Bitmap mit MS Paint abgespeichert wurde. Dieser war aber der Meinung er müsse im Bitmapheader eine Größe angeben die 2 Bytes größer war als die eigentlichen Daten. Diese 2 Bytes wurden auch aufgefüllt aber leider ist das TBitmap, welches ich zum Laden verwende, nicht so tolerant um darüber hinweg zu sehen. Und so bekommt man einen Fehler beim Laden. Den selben Fehler würde man auch bekommen wenn man das Bild in einem TImage anzeigen wollte.&lt;br /&gt;
&lt;br /&gt;
Abhelfen kann man dies in dem man ein [http://www.gimp.org/ alternatives Grafikprogramm (Gimp)] verwendet oder das Bild einmal mit dem Bildbetrachter [http://www.irfanview.de/ IrfanView] öffnet und abspeichert.&lt;br /&gt;
&lt;br /&gt;
Es muss nicht bei jedem mit MS Paint abgespeicherten Bild auftreten.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24582</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24582"/>
				<updated>2010-01-12T17:54:56Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''Mipmaps direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlgen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbüergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS untersützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für Normalmaps) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben. Für Photoshop empfiehlt sich das Plugin von [http://developer.nvidia.com/object/photoshop_dds_plugins.html Nvidia]. Es bietet sehr viele Funktionen, inklusive einer Vorschau und der Möglichkeit verschiedene Einstellungssets zu speichern und zu laden :&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[Glbitmap_loader|glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24581</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24581"/>
				<updated>2010-01-12T17:54:09Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''Mipmaps direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlgen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbüergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS untersützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für Normalmaps) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben. Für Photoshop empfiehlt sich das Plugin von [http://developer.nvidia.com/object/photoshop_dds_plugins.html Nvidia]. Es bietet sehr viele Funktionen, inklusive einer Vorschau und der Möglichkeit verschiedene Einstellungssets zu speichern und zu laden :&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[glBitmap|Glbitmap_loader]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24580</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24580"/>
				<updated>2010-01-12T17:53:34Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''Mipmaps direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlgen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbüergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS untersützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für Normalmaps) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben. Für Photoshop empfiehlt sich das Plugin von [http://developer.nvidia.com/object/photoshop_dds_plugins.html Nvidia]. Es bietet sehr viele Funktionen, inklusive einer Vorschau und der Möglichkeit verschiedene Einstellungssets zu speichern und zu laden :&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[glBitmap_loader]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24579</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24579"/>
				<updated>2010-01-12T17:52:36Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''Mipmaps direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlgen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbüergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS untersützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;br /&gt;
&lt;br /&gt;
=== Sonstige Formate ===&lt;br /&gt;
DDS kann zusätzlich noch eine Reihe weiterer Formate speichern. Darunter Standardformate (unkomprimiert), also z.B. 8-Bit ARGB, Palettenformate und spezielle Formate wie DXT5_NM (für Normalmaps) und das verbesserte Normalmapformat 3DC (von ATI entwickelt, besser für Normalmaps geeignet als DXT5_NM).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Nutzung ==&lt;br /&gt;
&lt;br /&gt;
=== Anwendungen ===&lt;br /&gt;
Für alle aktuellen Bildbearbeitungsprogramme und 3D-Modeller dürfte es inzwischen (wenn nicht bereits integriert) Importer und Exporter für dieses Format geben. Für Photoshop empfiehlt sich das Plugin von [http://developer.nvidia.com/object/photoshop_dds_plugins.html Nvidia]. Es bietet sehr viele Funktionen, inklusive einer Vorschau und der Möglichkeit verschiedene Einstellungssets zu speichern und zu laden :&lt;br /&gt;
&lt;br /&gt;
[[Datei:nv_dds_plugin_photoshop.jpg‎ ]]&lt;br /&gt;
&lt;br /&gt;
=== Betriebssystem ===&lt;br /&gt;
Für die meisten Entwickler ist es sehr praktisch direkt im Dateibrowser des Betriebssystems Texturen usw. sehen zu können. Leider bieten Betriebssysteme für das DDS-Format im Regelfall keine Vorschau, allerdings gibt es auch hier Plugins die sich direkt in den Dateibrowser einklingen, auch von NVidia. Leider funktioniert dies jedoch nur in 32-Bit Umgebungen, für 64-Bit Betriebssysteme muss man also woanders nach Alternativen suchen, z.B. [http://mysticcoder.net/mysticthumbs/ MysticThumbs] (Freeware).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
Inzwischen gibt es auch für Delphi mit Lossys [[glBitmap]] eine Bibliothek mit der man direkt DDS-Texturen laden kann. Alternativ kann man auch direkt den (etwas älteren) Loader von Mars [http://delphigl.com/forum/viewtopic.php?f=3&amp;amp;t=2486&amp;amp;p=18339&amp;amp;hilit=dds#p18339 aus unserem Forum] nehmen.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24578</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24578"/>
				<updated>2010-01-12T17:37:41Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
== Was kann man in DDS ablegen? ==&lt;br /&gt;
DDS speichert neben '''2D-Texturen''' auch '''[[Cubemap|Cubemaps]]''' und '''Volumentexturen (3D-Texture)'''. Besonders bei den [[Cubemap|Cubemaps]] ist es sehr praktisch diese alle in einer Datei ablegen zu können, was mit DDS problemlos möglich ist.&lt;br /&gt;
&lt;br /&gt;
Eines der wichtigsten Features ist jedoch die Möglichekit '''Mipmaps direkt in der Textur speichern zu können'''. Dadurch hat man zum einen direkten Einfluss auf die Generation der Mipmaps (können je nach Plugin sogar komplett selbst erstellt werden oder werden von diesem mit anpassbaren Parametern errrechnet). Bei allen anderen Formaten muss man diese entweder über [[gluBuildMipMaps]] generieren lassen, was sehr langsam ist, also die Ladezeiten der Anwendung stark erhöht und keinerlei Einstellungen zulässst, oder man lässt die Mipmaps auf aktuelleren Karten direkt in der Hardware generieren (passiert über die entsprechende Extension). DDS stellt hier also den Idealfall dar, denn die dort abgelegten Mipmaps werden direkt mit der Textur in den VRAM übertragen.&lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;br /&gt;
&lt;br /&gt;
=== Komprimierte Formate (fester Kompressionsratio) ===&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
!Format&lt;br /&gt;
!Ratio&lt;br /&gt;
!BPP&lt;br /&gt;
!Kanäle&lt;br /&gt;
!Bemerkung&lt;br /&gt;
|-&lt;br /&gt;
|DXT1&lt;br /&gt;
|8:1&lt;br /&gt;
|4&lt;br /&gt;
|(A)RGB&lt;br /&gt;
|Wahlweise mit 1 Bit Alpha&lt;br /&gt;
|-&lt;br /&gt;
|DXT3&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Expliziter Alphakanal&lt;br /&gt;
|-&lt;br /&gt;
|DXT5&lt;br /&gt;
|4:1&lt;br /&gt;
|8&lt;br /&gt;
|ARGB&lt;br /&gt;
|Interpolierter Alphakanal&lt;br /&gt;
|}&lt;br /&gt;
Da alle diese komprimierten Formate einen festen Kompressionsratio aufweisen, sollte man vorher überlgen ob bzw. welches dieser Formate für die entsprechende Textur in Frage kommt. Also Beispiel sei hier ein blauer Himmel mit weichen Farübergängen genannt, der durch die feste Kompression u.U. so schlecht aussehen kann dass man hier ein unkomprimiertes Texturformat wählen muss, denn durch die feste Kompression können ggf. ungewollt harte Farbüergänge entstehen die störend auffallen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:dds_differenz.jpg]]&lt;br /&gt;
&lt;br /&gt;
Auf obigem Bild sieht man rechts die um ein vielfaches (Faktor 100) verstärkte Differenz zwischen der Grundversion (PNG, verlustfrei) und der als DXT gespeicherten Version der linken Textur. In der Praxis fällt der Unterschied natürlich nicht so stark aus, ist aber je nach Textur mit bloßem Auge zu erkennen.&lt;br /&gt;
&lt;br /&gt;
=== Fließkommaformate (unkomprimiert) ===&lt;br /&gt;
Besonders in letzter Zeit hat sich auch in der 3D-Programmierung sog. HDR durchgesetzt (High Dynamic Range), mit welchem man realistische Lichtverältnisse und v.a. Wechsel dieser Lichterverähltnisse sehr gut simulieren kann (z.B. wenn man von einen dunklen Tunnel verlässt, dann brauchen die Augen normalerweise kurz um sich auf die Helligkeit einzustellen). Dazu benötigt man Texturformat die pro Kanal mehr als 8 Bit speichern können, und auch hier kann man DDS nutzen. Hinweis : DDS untersützt auch Integerformate mit mehr als 8 Bit pro Kanal (16 Bit), die auf alten Karten für HDR genutzt werden können, dann aber nicht so gute Ergebnisse erzielen.&lt;br /&gt;
&lt;br /&gt;
Das DDS-Format unterstützt sowohl Fließkommaformate mit '''16-Bit pro Farbkanal''' (max. 64 Bit) als auch Formate mit '''32-Bit pro Farbkanal'' (max. 128 Bit).&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:dds_differenz.jpg&amp;diff=24577</id>
		<title>Datei:dds differenz.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:dds_differenz.jpg&amp;diff=24577"/>
				<updated>2010-01-12T17:26:46Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Vielfach versärkte Darstellung der Differenz zwischen Grundbild und DDS-Bild&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vielfach versärkte Darstellung der Differenz zwischen Grundbild und DDS-Bild&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24576</id>
		<title>DDS</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=DDS&amp;diff=24576"/>
				<updated>2010-01-12T17:00:50Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Seite neu angelegt und mit Informationen befüllt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Was ist DDS? ==&lt;br /&gt;
DDS steht für &amp;quot;'''D'''irect '''D'''raw '''S'''urface&amp;quot; und ist ein eigenes für Texturen (und damit 3D-Anwendungen) entwickeltes Bildformat von Microsoft. Im Gegensatz zu herkömmlichen Bildformaten bringt es daher einige sehr wichtige Funktionen mit, die es '''für die 3D-Programmierung als perfektes Texturformat prädestinieren'''. Das Format ist zudem frei nutzbar, es fallen also keine Lizenzgebühren an, und man bewegt sich auch nicht in einem Graubereich, denn diverse &amp;quot;freie&amp;quot; Bildformate sind eigentlich nur bedingt frei nutzbar. Während normale Bildformate feste Spezifikationen besitzen und nur zu einem gewissen Grad anpassbar sind (z.B. PNG mit 8 Bit oder 24 Bit, Kompressionsrate bei JPG, etc.) ähnelt DDS mehr einem Containerformat (ähnlich wie bei Videocodecs) und kann unterschiedlichste Texturinformationen beinhalten. &lt;br /&gt;
&lt;br /&gt;
== Welche Formate kann DDS? ==&lt;br /&gt;
Im DDS-Format können so gut wie alle aktuell genutzten Texturformate abgelegt werden. Das Format ist zudem erweiterbar, sollte es also irgendwann z.B. neue Grafikkarten mit neuen Kompressionsformaten geben, kann DDS erweitert werden. Folgende Format (evtl. gibt es noch wietere, die Liste basiert auf dem Plugin von NVidia) können dort gespeichert werden :&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:nv_dds_plugin_photoshop.jpg&amp;diff=24575</id>
		<title>Datei:nv dds plugin photoshop.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:nv_dds_plugin_photoshop.jpg&amp;diff=24575"/>
				<updated>2010-01-12T16:52:17Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Screenshot des DDS-Exportplugins für Adobes Photoshop&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Screenshot des DDS-Exportplugins für Adobes Photoshop&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_2D&amp;diff=24574</id>
		<title>Tutorial 2D</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_2D&amp;diff=24574"/>
				<updated>2010-01-12T16:47:43Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Welches Bildformat ist das richtige? */  Paragraph über DDS erweitert, DDS als bestes Format für Fortgeschrittene markiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=2D mit OpenGL - &amp;quot;Nicht jeder benötigt 3 Dimensionen&amp;quot;=&lt;br /&gt;
&lt;br /&gt;
==Einleitung==&lt;br /&gt;
&lt;br /&gt;
Bei der Erwähnung einer API wie OpenGL denken die meisten eigentlich eher an 3D, und sind der festen (aber sehr wohl falschen) Überzeugung eine solche API sei für reine 2D-Anwendung überdimensioniert oder gar ungeeignet. Das dies nicht der Fall ist möchte ich mit diesem (vor allem an Einsteiger gerichtet, denn die Könner wissen wohl was man mit der GL so alles machen kann) Tutorial zeigen und auch gleich mit mehreren praktischen Beispielen aufweisen das 2D mit OpenGL nicht nur möglich ist, sondern auch noch sehr viel einfacher (selbst mit der GDI ist 2D komplizierter) ist und dabei jede Menge Vorteile mit sich bringt.&lt;br /&gt;
&lt;br /&gt;
==Welche Vorteile bringt mir die GL für eine 2D-Anwendung?==&lt;br /&gt;
&lt;br /&gt;
Dies ist wohl das wichtigste Kapitel und sollte zugleich auch mit diversen Vorurteilen und Missverständnissen aufräumen. Denn gerade der 3D-Bereich ist es in dem seit Jahren fast monatlich neue Techniken entworfen werden und der dafür sorgt das v.&amp;amp;nbsp;a. Grafikkarten immer leistungsstärker werden, während der 2D-Bereich seit seligen VLB-Zeiten (= Vesa-Local-Bus, alte Haudegen kennen diese Grafikkartengeneration sicherlich noch) keine Innovationen mehr erlebt hat (und warum auch? Im 2D-Bereich reicht ein gutes Bild zusammen mit passabler Darstellungsgeschwindigkeit).&lt;br /&gt;
&lt;br /&gt;
Deshalb gibt es jetzt gleich mal die wichtigsten Punkte warum man denn gerade OpenGL (D3D würde hier auch zählen, aber das haben wir GL'ler ja nicht so gerne) für die 2D-Darstellung nutzen sollte:&lt;br /&gt;
&lt;br /&gt;
*'''Hardwarebeschleunigung'''&lt;br /&gt;
:Moderne Grafikkarten können inzwischen über 200 Millionen Dreiecke pro Sekunde rendern und besitzen brachiale Füllraten jenseits der 2.000 M(Texel/Pixel)/s. Das bedeutet also das man selbst auf älteren Grafikkarten sehr komplexe 2D-Szenen mit Geschwindigkeiten jenseits der 100 FpS (= Frames per Seconds ~ Bilder pro Sekunde) darstellen kann, während man mit der GDI schon bei einfachen 2D-Grafiken Geschwindigkeitsprobleme bekommen würde.&lt;br /&gt;
&lt;br /&gt;
*'''&amp;quot;Kostenlose&amp;quot; Objektsortierung'''&lt;br /&gt;
:Eine 3D-API braucht einen Tiefenpuffer um zu erkennen ob Fragmente verdeckt sind oder nicht und damit Overdraw zu vermeiden. Eine 2D-Anwendung kann diesen Tiefenpuffer aber auch nutzen, nämlich um Objekte zu sortieren. Man nutzt dann die Z-Koordinate der Objekte (= Tiefenkoordinate) quasi als Layer um zu kennzeichnen welches Objekt auf welcher &amp;quot;Höhe&amp;quot; liegt. Wenn man also z.&amp;amp;nbsp;B. einen 2D-Topdown-Shooter entwickelt bei dem der Spieler mit seinem Flugzeug über den Boden fliegt, dann nutzt man den Z-Puffer um die API (die das dann der Hardware überlässt) seine Objekte sortieren zu lassen. Das Flugzeug bekommt dann einen niedrigen Z-Wert (=oben) und Objekte auf dem Boden einen hohen Tiefenwert (=unten/hinten). Die Sortierung übernimmt dann die Grafikkarte und wir müssen uns darum keine Gedanken machen. Würden wir die Anwendung z.&amp;amp;nbsp;B. über die GDI realisieren, müssten wir diese Objekte selbst entsprechend ihrer Höhe sortieren.&lt;br /&gt;
&lt;br /&gt;
*'''Jede Menge hardwarebeschleunigte Spezialeffekt'''&lt;br /&gt;
:Wie schon oben erwähnt haben im 3D-Bereich innerhalb der letzten Jahre sehr viele Innovationen stattgefunden. Warum sollte man diese also nicht auch für seine 2D-Anwendung nutzen? Klingt logisch und macht auch Sinn! So bietet OpenGL alle Arten von Effekten die auch in einer 2D-Anwendung nützlich sein können. Darunter solche Sachen wie den Alphatest (der dafür sorgt das maskierte Teile eines Objektes transparent sind), Blending und natürlich (auch wenn das jetzt für erfahrene GL'ler sehr trivial klingt) hardwarebeschleunigte Rotation und Skalierung; was zur Folge hat das man seine Objekte nicht für verschiedene Auflösungen in verschiedenen Größen erstellen muss. Für Fortgeschrittene gibt es dann natürlich noch solche Sachen wie Shader, mit denen man Teile der OpenGL-Pipeline durch eigene (kleine) Programme ersetzen kann (entweder in Assemblerform oder aber in der neuen GL-HLSL). Dadurch bietet sich dann ein quasi unendlich großes Spektrum an möglichen Effekten, und das wohlgemerkt alles hardwarebeschleunigt!&lt;br /&gt;
&lt;br /&gt;
*'''Plattformübergreifend'''&lt;br /&gt;
:Auch ein großer Vorteil von OpenGL. Die Tatsache das die GL unter diversen Betriebssystemen verfügbar ist (im Gegensatz zu GDI oder gar DirectX) macht die eigenen Programme recht portabel (einschränkend ist hier halt nur die Verfügbarkeit der genutzten Programmiersprache auf dem passenden OS). Unterstützt werden alle größeren Betriebssysteme wie Windows, Linux, MacOS und Solaris.&lt;br /&gt;
&lt;br /&gt;
:Ganz nebenbei wurde vor kurzem mit [http://www.khronos.org/opengles/2_X/ OpenGL ES] ein mobiler Standard für OpenGL geschaffen, wodurch es dann auch möglich ist auf mobilen Geräten (Handys, PDAs, Handhelds) OpenGL zu nutzen. Und gerade dort sind 2D-Spiele (aufgrund der oft mangelnden Leistung der Geräte) ja noch stark verbreitet.&lt;br /&gt;
&lt;br /&gt;
So viel also zu den wichtigsten Vorteilen zur OpenGL unter 2D. Natürlich gibt es noch weiter Dinge die OpenGL für 2D-Anwendungen attraktiv machen, aber allein die oben genannten Gründe sollten jedermann überzeugt haben. Und alle die wirklich mal wissen wollen wie gut OpenGL denn für solche Anwendungen geeignet ist, sollten sich unbedingt eine neuere Version des MacOS ansehen, denn das benutzt OpenGL zur Darstellung seiner GUI.&lt;br /&gt;
&lt;br /&gt;
==Und welche Nachteile gibt es?==&lt;br /&gt;
&lt;br /&gt;
Nichts was der Mensch bisher erfunden hat (mal abgesehen von der Spaltung des Atoms ;) ) hat nur Vorteile. Genauso sieht es auch aus wenn man die OpenGL für seine 2D-Anwendung nutzen will. Welche genau das sind will ich hier grob auflisten.&lt;br /&gt;
&lt;br /&gt;
*'''Ohne 3D-Beschleuniger mit passenden Treibern geht nichts'''&lt;br /&gt;
:Klingt logisch, oder? OpenGL ist eine 3D-API und da 2D nichts weiter als die (fast vollständige) Vernachlässigung der Z-Koordinate ist, kommen wir um einen 3D-Beschleuniger nicht herum, der dazu auch noch einen Treiber mitbringen muss der OpenGL unterstützt. Allerdings schritt der Fortschritt auf diesem Gebiet der IT-Technik in den letzten Jahren so rasant voran wie sonst nirgendwo, und wir werden nur sehr selten auf Rechner stoßen in denen Hardware agiert die keine 3D-Beschleunigung bietet. Ergänzend dazu sollte allerdings trotzdem immer der neuste Treiber installiert sein, denn besonders die in WindowsXP integrierten Grafikkartentreiber wurden ihrer OpenGL-Funktionalität entraubt (Man riecht hier förmlich die Konkurrenz zwischen D3D und der GL). Also ist dies im Endeffekt ein Nachteil der inzwischen kaum noch halt findet und in Zukunft total vernachlässigt werden kann.&lt;br /&gt;
&lt;br /&gt;
*'''Hardwarelimitationen'''&lt;br /&gt;
:Einer der größten Nachteile einer jeden 3D-API die auf Hardwarebasis arbeitet sind die Limitationen die die Hardware mitbringt. Jeder Grafikkartentyp hat andere, was mitunter dazu führen kann das die selbstverfassten OpenGL-Anwendungen nicht auf allen Rechnern laufen. Da wir uns in diesem Tutorial (2D ist ja recht anspruchslos) allerdings in den Niederungen der OpenGL-Funktionalität bewegen, dürfte es hier kaum Probleme geben. Einzig die Tatsache das vor allem ältere 3D-Beschleuniger mit großen Texturen Probleme haben könnte hier und da Schwierigkeiten machen. Wer aber keine Texturen größer 1024x1024 Pixel nutzt und dazu noch sparend mit dem Speicher der Grafikkarte umgeht (nicht jede Grafikkarte hat 128 Mbyte Grafikspeicher oder gar mehr). Einige Leute werden sich übrigens evtl. dadurch verunsichert fühlen das ihnen jemand gesagt hat, man könnte unter OpenGL nur Texturen nutzen die der Dimension 2^n*2^n entsprechen. Das ist grundlegend korrekt, aber wir nutzen hier einen Texturenloader der [[gluBuildMipMaps]] benutzt um [[MipMaps]] (verschiedene Detailstufen) für unsere Texturen zu erstellen. Diese Funktion schluckt jede Größe (sofern diese kleiner oder gleich dem Hardwarelimit ist) und passt die Texturen dann entsprechend an eben genanntes Limit an, also müssen wir uns um diese so oft erwähnte Limitation keine Sorgen machen. Wer zu dem Thema Hardwarelimitation mehr wissen will, der sollte unbedingt mal auf [http://www.delphi3d.net/ Tom Nuydens Seite] vorbei schauen. Dort gibt es eine riesige Datenbank in der fast alle Grafikkarten mit ihren entsprechenden OpenGL-Fähigkeiten vertreten sind.&lt;br /&gt;
&lt;br /&gt;
*'''Filtering'''&lt;br /&gt;
:Zugleich ein großer Vorteil, aber je nach Situation auch ein Nachteil. OpenGL filtert Texturen (sofern man das via GL_LINEAR so will) bilinear, was man auch tunlichst aktiviert lassen sollte (GL_NEAREST filtert nicht, sieht dann aber auch scheußlich blockig aus). Dadurch wirken Texturn meist etwas verschwommen. Ich für meinen Teil umgehe dies aber ganz einfach, denn in fast jedem Bildbearbeitungsprogramm gibt es eine Funktion mit der man ein Bild scharfzeichnen kann. Das sieht auf den ersten Blick dann zwar überzeichnet aus, aber wenn OpenGL das Bild dann als Textur bilinear filtert, heben sich Filtering und Scharfzeichnung gegenseitig fast auf. Das hat sich in meinen Anwendungen bisher bewährt und ist nicht wirklich viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
Um dieses Kapitel hier abzuschließen sei noch gesagt das man ohne 3D-Beschleuniger nicht unbedingt auf OpenGL verzichten muss. Brian Paul hat mit [http://www.mesa3d.org/ Mesa3D] nämlich ein Projekt am laufen das OpenGL-DLLs zur Verfügung stellen die komplett über die CPU ablaufen. So kann man dann OpenGL-Anwendungen mit einer etwas schnelleren CPU trotz fehlendem 3D-Beschleuniger nutzen, oder auf Funktionen ausprobieren die von der (zu alten) Grafikkarte nicht unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
==Die Grundlagen==&lt;br /&gt;
&lt;br /&gt;
Sollte sich der geneigte Leser nun also doch für die GL entschieden haben, so widmen wir uns dann jetzt den Grundlagen der 2D-Darstellung unter OpenGL. Viele Sachen die man bei einer 3D-Anwendung beachten muss, sind hier eigentlich zu vernachlässigen. Wer also schon mal eine kleine 3D-Anwendung unter OpenGL geschrieben hat wird hier sicherlich keine Problem bekommen. Da sich dieses Tutorial aber an blutige (mhh, lecker) Einsteiger richtet, versuche ich so genau und einfach wie möglich zu erklären was man machen muss und v.&amp;amp;nbsp;a. warum. Genau deshalb habe ich auch für einen Großteil der hier erwähnten Techniken im Download zu diesem Tutorial (siehe unsere Files-Sektion und dort unter VCL-Source) jeweils ein eigenes Beispielprogramm + Quellcode (und natürlich ausgiebigen Kommentaren) geschrieben. Wenn zu dem jeweiligen Kapitel ein solches im Download enthalten ist, dann steht das ''kursiv'' unter der Überschrift des Kapitels.&lt;br /&gt;
&lt;br /&gt;
==Die Projektion==&lt;br /&gt;
&lt;br /&gt;
Wie bekannt (sein sollte), besitzt OpenGL im Groben zwei wichtige Matrizen. Zum einen die Modellansichtsmatrix, in der man im Normalfall seine Szene (egal ob 2D oder 3D) rendert und (für dieses Kapitel wichtiger) die Projektionsmatrix. Diese Matrix lässt sich am besten mit der Linse einer Kamera vergleichen und legt fest wie die Objekte auf den Bildschirm projiziert werden (wer mitdenkt wird jetzt wissen warum diese Matrix so genannt wurde). In einer 3D-Anwendung setzen wir (meist über [[gluPerspective]]) eine Projektionsmatrix die dafür sorgt das unsere Objekte perspektivisch korrekt verzerrt werden (so wie es im echten Leben auch ist). Da Bilder aber mehr als tausend Worte sagen zeige ich das anhand der unteren Bildreihe, die einen Würfel an verschiedenen Positionen auf der X-Achse zeigt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_1.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Der Würfel wurde auf den beiden Bildausschnitten links und rechts jeweils um 40 Einheiten auf der X-Achse verschoben und man kann sehr gut sehen das die Seiten des Würfels perspektivisch verzerrt werden, also weiter entfernte Kanten kleiner erscheinen (wie im realen Leben, das kann man ja prima mit nem würfelähnlichem Objekt nachprüfen). Diese Art der Darstellung ist für 3D gut geeignet, aber für unseren Zweck nicht. Denn wir wollen ja das unser Objekt, egal an welcher Bildschirmposition es sich befindet, gleich aussieht.&lt;br /&gt;
&lt;br /&gt;
Dazu gibt es unter OpenGL den sog. orthogonalen Modus, der dafür sorgt das unser [[Frustum]] (Sichtkegel) nicht wie bei der 3D-Projektion kegelförmig ist (kleine Seite beim Betrachter, große Seite am Ende des Sichtfeldes), sondern wie eine Box aussieht. Für technisch interessierte hier der Vergleich zwischen dem 3D- und dem 2D-Frustum :&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_2.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir das Frustum (~Sichtbereich) für die orthogonale Projektion (also 2D) und rechts für die perspektivische Projektion (3D). In diesem Tutorial interessieren wir uns wie gesagt für ersteres Frustum, welches sich über die Funktion [[glOrtho]] erstellen lässt. Diese Funktion will von uns die Dimensionen haben die wir unserem Viewport geben wollen. Ich empfehle hier übrigens immer einen festen Wert der einer der gängigen Auflösungen (z.&amp;amp;nbsp;B. 640x480, 800x600) entspricht. Der feste Wert hat übrigens den Vorteil das unsere Anwendung von der vom Nutzer gewählten Bildschirmauflösung unabhängig ist. Wir müssen dann also nicht mehr umrechnen wo unser Objekt jetzt in der gewählten Auflösung wäre und wie groß es dort sein müsste. Dadurch das wir immer die selben virtuellen Koordinaten haben, überlassen wir der GL (bzw. der Grafikkarte) die Umrechnung. Wenn wir also eine virtuelle Auflösung von 640x480 an glOrtho übergeben, und ein Objekt zentriert bei 320x240 rendern, dann wird dieses egal in welcher Auflösung immer in der Mitte des Schirms gerendert. Die Umrechnung macht wie gesagt OpenGl (oder besser gesagt die Grafikkarte). Zusätzlich übergeben wir der Funktion dann noch die Z-Reichweite. Hier kann man beliebig wählen, und muss nicht wie in 3D darauf achten Z-Near und Z-Far so zu wählen das die Auflösung des Tiefenpuffers nicht unnötig verschwendet wird (z.&amp;amp;nbsp;B. mit einem Z-Near von 0.1 oder gar kleiner). Für Z-Near nehme ich gewöhnlich 0 und für Z-Far einen Wert der dafür sorgt das ich alle Objekte so sortieren kann das ihre Z-Position auf einen Integerwert fällt. Als kleines Codebeispiel könnte unsere Projektionsmatrix nun so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glMatrixMode(GL_PROJECTION);&lt;br /&gt;
glLoadIdentity;&lt;br /&gt;
glViewport(0,0,ClientWidth,ClientHeight);&lt;br /&gt;
glOrtho(0,640,0,480,0,128);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um den optischen Vergleich zur oben erwähnten 3D-Projektion zu zeigen, gibt es wieder ein Bild des Würfels, diesmal allerdings mit 2D-Projektion:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_3.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Das sieht auf den ersten Blick zugegeben recht langweilig aus, stellt aber genau den selben Szenenverhalt dar wie die Ansicht ein paar Zeilen weiter oben. Diesmal allerdings mit der gerade besprochenen orthogonalen Ansicht, die als Grundlage für unsere 2D-Projektion dient.&lt;br /&gt;
&lt;br /&gt;
So viel also zur 2D-Projektion und hoffentlich hat das hier jeder verstanden. Die orthogonale Projektion ist ein essentieller Bestandteil einer jeden 2D-Anwendung unter OpenGL und sollte daher allen Interessierten ein Begriff sein. Falls das hier jemandem zu technisch war, im Forum werden weitergehende Fragen gerne beantwortet.&lt;br /&gt;
&lt;br /&gt;
Noch als kleiner Nachtrag: Wer sich mal die Parameter angesehen hat die glOrtho will, wird bemerkt haben das wir in obigem Quellcode (zumindest augescheinlich) Top mit Bottom verwechselt haben (sprich es sollte 0,640,480,0 statt 0,640,0,480) heißen. Das hat allerdings seine Richtigkeit, denn in OpenGL liegt der Ursprung des Koordinatensystems in der unteren linken Bildschirm(oder Fenster)ecke, wobei er bei Windows in der oberen Ecke liegt. Unter OpenGL liegt also quasi der &amp;quot;Boden&amp;quot; oben, genau umgekehrt wie unter Windows. Genau deshalb übergeben wir als &amp;quot;Oben&amp;quot; an glOrtho den eigentlichen Boden des Viewports. Das klingt verwirrend, aber ist im Endeffekt gar nicht so schwer zu behalten, besonders dann nicht wenn man sich folgende Illustration mal näher ansieht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_11.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Das sollte man immer in Hinterkopf behalten, und unter 3D ist es genauso. Während ein positiver Y-Wert Objekte in einem Windowsfenster nach unten verschiebt, geschieht unter OpenGL genau das Gegenteil. Wer sich mit dieser Tatsache nicht anfreunden kann, der kann auch gerne glOrtho dazu nutzen die 2D-Matrix von OpenGL an die Windowsgegebenheiten anzupassen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glOrtho(0,640,480,0,0,128);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und schon verhält es sich unter OpenGL genauso wie unter Windows. Positive Y-Koordinaten zeigen nach unten. Allerdings muss man hier dann auch drauf achten die gerenderten Objekte an diese Gegebenheit anzupassen. Man muss diese also quasi auf den Kopf stellen, damit sie mit der neuen Matrix korrekt angezeigt werden. Das geht aber ganz leicht, indem man beim rendern von Quads oder anderen texturierten Primitiven ganz einfach die T-Texturkoordinaten vertauscht.&lt;br /&gt;
&lt;br /&gt;
==Darstellung der 2D-Objekte==&lt;br /&gt;
&lt;br /&gt;
Einige 2D-Interessierte haben sich sicherlich schon mal im Funktionsumfang von OpenGL umgesehen und bemerkt, dass es dort eigentlich gar keine Funktionen gibt um Dinge in 2D zu zeichnen. Auf den ersten Blick sieht das auch wirklich so aus, aber man darf halt nie vergessen dass OpenGL primär für den 3D-Bereich entworfen wurde und sich 2D-Sachen dann nur über 3D-Techniken realisieren lassen. So auch die Darstellung unserer 2D-Objekte, für die wir aus genau diesem Grund eine 3D-Technik anwenden müssen, nämlich das sog. Texturemapping (Den Begriff &amp;quot;Textur&amp;quot; gibt's übrigens auch im deutschen Sprachgebrauch, aber gängiger ist die korrekte Übersetzung &amp;quot;Oberfläche&amp;quot;). Unter OpenGL werden ja alle Objekte aus verschiedenen Primitiventypen zusammengesetzt (Dreiecke, Rechtecke, usw.) und diese Objekte kann man mit einer Textur belegen die dann auf dieser Oberfläche &amp;quot;angezeigt&amp;quot; wird. Diese Textur lädt man im Normalfall aus einer vorher erstellten Bilddatei unter Nutzung eines [[Texture_Loader|Texturenloaders]] (alternativ kann man den sich natürlich auch selbst schreiben), der diese Textur für die Grafikkarte vorbereitet (also z.&amp;amp;nbsp;B. ein BMP-Bild vom BGR-Format ins RGB-Format bringt) und dann auf dieser ablegt. Danach kann diese Textur an jeder Stelle im Programm auf eine Primitve &amp;quot;geklebt&amp;quot; werden, und genauso machen wir das auch in unserer 2D-Anwendung.&lt;br /&gt;
&lt;br /&gt;
Allerdings müssen wir keine komplexen Formen darstellen, da unsere Objekte ja nicht 3D sind, sondern (meistens) schon in einem anderen Programm erstellt (oder vorgerendert wurden) und als Bilddatei abgelegt wurde. Wir laden und stellen dann also nicht die 3D-Daten dieses Modells dar (was bei komplexen 2D-Objekten wohl eh zu viel wäre), sondern kleben diese schon fertige Bilddatei mittels einer Textur auf ein Rechteck (in der GL-Terminologie &amp;quot;Quad&amp;quot; genannt, vom Primitiventyp GL_QUADS). Hoffe mal das kam gut rüber, aber ich verdeutliche dass dann besser nochmal anhand einer kleinen &amp;quot;Bilderserie&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_4.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Oben sei mal kategorisch der Vorgang geschildert um ein vorgerendertes 3D-Objekt als Textur in seine 2D-Anwendung zu bekommen. Rechts sieht man das 3D-Modell, das dann aus der gewünschten Ansicht (im obigen Falle von der Seite) im 3D-Modellierungsprogramm gerendert wird. Dieses Rendering speichert man dann in einem Format ab das der Texturenloader verarbeiten kann, lädt dies in seine OpenGL-Anwendung und stellt dies dann auf z.&amp;amp;nbsp;B. einem Quad dar (siehe letztes Bild). Natürlich spielt es keine Rolle ob man seine 2D-Objekte vorrendert oder diese von Hand zeichnet, wobei den meisten wohl Ersteres besser von der &amp;quot;Hand&amp;quot; geht.&lt;br /&gt;
&lt;br /&gt;
===Welches Bildformat ist das richtige?===&lt;br /&gt;
&lt;br /&gt;
Bevor wir nun weiter auf das Thema eingehen kümmern wir uns um die '''Frage nach dem richtigen Bildformat''' für unsere Texturen. Bildformate gibt's wie Sand am Meer, aber für unseren Zweck eignen sich nur sehr wenige (eigentlich nur ein einziges). Ich zähle die verbreitetsten Formate kurz auf und sag auch warum (oder warum nicht) und wofür man diese verwenden kann:&lt;br /&gt;
&lt;br /&gt;
*'''Joint Photographic Experts Group (*.jpg; *.jpeg)'''&lt;br /&gt;
:Das in den Weiten des WWWs wohl verbreitetste Format ist für Texturen generell eher weniger zu empfehlen, und für 2D-Objekte erst recht nicht. Zum einen ist die in diesem Format genutzte Kompression verlustbehaftet (also verlieren unsere Texturen an Qualität) und außerdem hat dieses Format keine Möglichkeit Transparenzinformationen zu speichern. Diese benötigt man aber für 2D-Objekte, denn im Normalfall wollen wir den Hintergrund des Objektes ja durchsichtig machen (dazu gleich mehr). Also sollte dieses Format nur verwendet werden wenn wir etwas darstellen wollen das sehr viele Details enthält (dann fällt die verlustbehaftete Kompression nicht so stark auf) und keine transparenten Bereiche enthält.&lt;br /&gt;
&lt;br /&gt;
*'''Graphical Interchange Format (*.gif)'''&lt;br /&gt;
:Direkt aus der Steinzeit des IT-Sektors kommt das (im Netz noch weit verbreitet) GIF-Format. Für unsere Zwecke ist es total unbrauchbar. Es ist eine Palettenformat, das maximal 256 verschiedene Farben unterstützt, allerdings inklusive Transparenzinformationen. Aber die maximal 256 Farben und die kaum vorhandene Kompression machen es für unseren Zweck nutzlos. Die Tatsache dass es Animationen unterstützt ist zwar im Internet für kleine animierte Sachen ganz toll, aber hilft uns auch nicht, denn dazu überwiegen die Nachteile zu stark&lt;br /&gt;
&lt;br /&gt;
*'''Portable Network Graphic (*.png)'''&lt;br /&gt;
:Der Nachfolger des GIF-Formates. Eigentlich auch sehr gut für Texturen geeignet, denn neben einem Alphakanal (maximal 8 Bit) und 8 Bit pro Farbkanal unterstützt es auch verlustfreie Kompression (mit einem recht hohen Kompressionsfaktor). Nachteil ist allerdings der Aufbau des Formates, denn der Chunkaufbau macht das Laden recht schwer und bisher gibt es nur Loader die eine DLL-Datei mit sich schleppen. Alternativ kann man auf neuen Betriebssystemen jedoch via GDI+ auch PNG-Dateien direkt laden.&lt;br /&gt;
&lt;br /&gt;
*'''TARGA (*.tga)'''&lt;br /&gt;
:Dieses Format werden sicherlich nicht viele Einsteiger kennen, allerdings ist dies '''''das perfekte Format für unsere Bedürfnisse bzw. Texturen im Allgemeinen'''''. Es kann nämlich bis zu 8 Bit pro Farbkanal (also das was man heute als 32-Bit Farbtiefe bezeichnet) speichern (= 24 Bit für Farben) und dazu noch einen Alphakanal (maximal 8 Bit). Der Alphakanal ist sehr nützlich, denn in ihm kann man die Transparenzinformationen eines Bildes ablegen. Auch viele kommerzielle Titel nutzen dieses Format (u.&amp;amp;nbsp;a. Quake3), und das aus gutem Grund. Kompression wird auch unterstützt, und zwar verlustfrei in Form einer LZW-Kompression. Alles in allem ist das momentan das geeignetste Format für Texturen, zumal so gut wie jedes Bildbearbeitungsprogramm damit umgehen kann. Nebenbei ist dies Format auch recht einfach aufgebaut und damit auch recht leicht einzulesen.&lt;br /&gt;
&lt;br /&gt;
*'''BITMAP (*.bmp)'''&lt;br /&gt;
:Das BMP-Format dürfte sicherlich jedem ein Begriff sein, ist aber genauso wie GIF ein Relikt aus der Steinzeit. Es kann zwar genauso wie das TGA-Format neben den 8 Bits pro Farbkanal auch einen maximal 8 Bits großen Alphakanal anbieten, allerdings kommen damit nur recht wenige Bildbearbeitungprogramme klar. Ausserdem sind die Bilddaten hier im BGR-Format abgelegt, statt dem eher üblichem RGB-Format (Red, Green, Blue). Das ist zwar sehr leicht umzuwandeln, bzw. kann mit passender GL-Konstante auch direkt übergeben werden, aber trotzdem ist dieses Format in keinem Falle dem TARGA-Format vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
*'''DirectDraw Surface (*.dds)'''&lt;br /&gt;
:Ein sehr neues Format, das den Ursprung (wie am Namen zu erkennen) in Microsofts DirectX-Schnittstelle hat. Es ist ein recht modernes Format, das speziell für die Speicherung von Texturen entwickelt wurde. Allerdings ist das eher was für Fortgeschrittene, denn weder das Laden dieses Formates ist einfach, noch seine Speicherung (selbst teure Bildbearbeitungsprogramme brauchen ein passendes Plugin für DDS und bei der Erstellung des Formates muss man auf bestimmte Sachen achten). Aber ich wollte es hier trotzdem mal erwähnt haben, damit man sieht das es auch spezielle Formate für Texturen gibt, und wenn ihr euch eingearbeitet habt, dann könnt ihr im Forum mehr zu dem Format finden (Mars hat dort auch einen grundlegenden Loader gepostet), denn es ist recht interessant. Es unterstützt feste Kompressionsratios, Mip-Maps, 3D-Texturen, uvm. '''Für fortgeschrittene 3D-Programmierer sollte DDS also das Format der Wahl sein''', denn es wurde als einziges der verbreiteten Bildformate speziell für diesen Bereich konzipiert. Vor allem die Tatsache dass die Kompression dieses Formates von den Grafikkarten direkt unterstützt wird prädestiniert es für diesen Anwendungsfall. So spart man sowohl beim Hochladen als auch beim Rendern viel Busbandbreite, da die GPU die Textur auch intern komprimiert behandelt und spart logischerweise auch VRAM. Man darf sich allerdings nicht vom Platzverbrauch der eigentlichen Datei irrtieren lassen, denn das Kompressionsformat ist fest (z.B. 4:1, 6:1, etc.) statt variable wie u.A. bei JPGs. Aber dafür entspricht dann die Dateigröße exakt der Größe die auch im VRAM belegt wird. Allerdings sollte man hier genau wissen was man tut, da es sehr viele Foramte innerhalb des DDS geben kann (DXT1, DXT3, DXT5, Palette, Fließkomma, etc.) und es durchaus Texturen gibt die durch den festen Kompressionsratio schlecht aussehen können. Ein gutes Beispiel ist hier ein blauer Himmel mit Sonne und Wolken, der durch einen weichen Farbverlauf gekennzeichnet ist. Da bei DXT1/3/5 fest komprimiert wird kann dort die Bildqualität sehr stark leiden. Dann sollte man im DDS unkomprimiert ablegen. Ausserdem gibt es inzwischen auch einen recht brauchbaren Loader für DDS in Delphi, und Lossys [[glBitmap]] kann dieses Format auch laden.&lt;br /&gt;
&lt;br /&gt;
Die obige Liste dürfte also einen recht (groben) Überblick über die verbreiteten Bildformate geben, und für dieses Tutorial begnügen wir uns erstmal mit dem TARGA-Format. Das wurde übrigens bereits 1984 erfunden, ist aber trotzdem noch nicht veraltet, sorgt aber dafür das so ziemlich jedes Programm damit umgehen kann.&lt;br /&gt;
&lt;br /&gt;
Wer sich übrigens nicht auf einen fremden Texturenloader verlassen möchte, sondern sich selbst um das Einlesen der Bildformate kümmern will, der sollte mal eine Blick auf [http://www.wotsit.org wotsig.org] werfen, einer recht großen Bibliothek die es sich zur Aufgabe gemacht hat Spezifikationen für Dateiformate zu sammeln. Dort wird man zu jedem der oben gennannten Bildformate eine solche Spezifikation finden, anhand derer man dann selbst Laderoutinen schreiben kann.&lt;br /&gt;
&lt;br /&gt;
===Textur laden===&lt;br /&gt;
&lt;br /&gt;
Auch wenn es ein sehr simples Unterfangen ist eine Textur zu laden, werde ich hier trotzdem nochmal kurz darauf eingehen. Das Tutorial richtet sich ja an Einsteiger, und von daher kann es nicht schaden auch mal kurz zu zeigen wie man so eine Textur lädt. Nutzen tun wir dazu die ''Textures.pas'' (die im Original von Jan Horn stammt. Ein weitere guter Loader ist [[Glbitmap_loader|glBitmap.pas]]), die sich im Download des Beispiels für dieses Tutorial befindet. Der Loader kann JPG, BMP und TGA laden. Außerdem lädt er auch den Alphakanal aus einer TGA-Textur.&lt;br /&gt;
&lt;br /&gt;
Bevor wir die Textur laden können, benötigen wir eine Variable in der wir den Bezeichner der Textur speichern. OpenGL erstellt für alle Ressourcen eindeutige Bezeichner (Bezeichner hier in Form eines Integerwertes, also einer eindeutigen ID), so auch für Texturen. Dieser Bezeichner ist vom Typ glUInt (U=unsinged Int=Integer, also vorzeichenloser Ganzzahlwert, was in Delphi dem Variablentyp ''Cardinal'' entpricht). Deshalb deklarieren wir unseren Texturenbezeichner auch so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var&lt;br /&gt;
 MyTex : glUInt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn wir mehrere Texturen laden und verwalten wollen, bietet sich natürlich ein (dynamisches) ''array of glUInt'' an, aber das sind Delphigrundlagen die in diesem Tutorial nichts zu suchen haben.&lt;br /&gt;
&lt;br /&gt;
Das Laden der Textur geht nun dank der ''Textures.pas'' ganz einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;LoadTexture('MeineTextur.tga', MyTex, False);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Parameter sollten recht logisch sein, der erste gibt den Dateinamen der Textur an, der zweite das Texturobjekt (in das die ID der Textur geschrieben wird) und der letzte Parameter gibt an ob die Textur aus einer dem Programm angehängten Ressource geladen werden soll. Sollte der Ladevorgang erfolgreich gewesen sein, so müsste sich in ''MyTex'' ein Wert &amp;gt; 0 befinden, nämlich der eindeutige Bezeichner dieses Texturenobjektes.&lt;br /&gt;
&lt;br /&gt;
===Textur anwenden===&lt;br /&gt;
&lt;br /&gt;
Wer sich schonmal ein wenig über OpenGL schlau gemacht hat, der wird wissen dass die GL eine Statemachine ist. Das trifft auch auf Texturen zu, denn wenn eine Textur gebunden wurde, wird sie solange auf alle Primitiven angewendet, bis entweder eine andere Textur gebunden wurde oder das Texturemapping über [[glDisable]] abgeschaltet wird. Das hat besonders dann den Vorteil, wenn man viele Objekte mit der gleichen Textur rendern muss, denn Texturenwechsel sind recht kostspielig. Von daher sollte man also bei vielen Objekten eine Sortierung nach Textur vornehmen, dann diese Textur binden und danach dann alle Objekte die diese Textur besitzen rendern.&lt;br /&gt;
&lt;br /&gt;
Doch bevor Texturen überhaupt angezeigt werden, müssen wir OpenGL erstmal mitteilen das es diese auch anzeigen soll. Dazu gibt es die Funktion '''glEnable''', der man mit der Konstante '''GL_TEXTURE_2D''' mitteilt das wir die 2D-Texturierung aktivieren wollen (1D oder 3D-Texturen benötigen wir ja in diesem Tutorial nicht):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_TEXTURE_2D);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unglaublich einfach, oder? So schnell kann das dank einer gut durchdachten API wie OpenGL gehen. Jetzt wo wir der API erstmal gesagt haben dass wir gerne Texturen sehen möchten, müssen wir auch noch sagen welche Textur als nächstes auf unserer Primitiven gezeigt werden soll. Dazu bindet (~ aktiviert) man das passende Texturobjekt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D, MyTex);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von nun an werden alle folgenden Primitiven solange mit der hinter ''MyTex'' abgelegten Textur gerendert, bis das Texturemapping entweder deaktiviert wird oder wir eine andere Textur binden.&lt;br /&gt;
&lt;br /&gt;
===Transparenz===&lt;br /&gt;
&lt;br /&gt;
Eine wichtige Sache die es noch zu klären gibt ist Transparenz. Oben habe ich ja gesagt das wir unsere Objekte auf Quads kleben (über eine Textur), aber unsere vorgefertigten Objekte nur selten auch genau die Form eines Quads haben. Der Panzer auf der oben gezeigten Textur wird z.&amp;amp;nbsp;B. von sehr viel schwarz umgeben, das wir da natürlich nicht sehen wollen. Aber auch um die Transparenz brauchen wir uns unter OpenGL keine Sorgen zu machen, denn dafür gibt es den sog. Alphakanal der Textur, der angibt welche Teile einer Textur später transparent (oder besser gesagt gar nicht, aber dazu gleich mehr) gezeigt werden sollen. Aus diesem Grund haben wir uns mit dem TGA-Format auch ein Format gewählt das diesen Kanal direkt im Bild speichern kann, sodass wir diesen nicht extra erstellen oder aus einer seperaten Bilddatei laden müssen.&lt;br /&gt;
&lt;br /&gt;
Wie man den Alphakanal nun in die Textur bekommt hängt davon ab wie man seine Textur erstellt. Wer seine Objekte von Hand malt, der muss den Alphakanal im Bildbearbeitungsprogramm selbst erstellen. Wer seine Objekte allerdings vorrendert, der kann diese Arbeit im Normalfall von der 3D-Software erledigen lassen, die Alphainformationen direkt mitexportieren kann. Als kleiner Hinweis sei übrigens gesagt das man beim Rendering des Objektes im 3D-Programm die Kantenglättung deaktivieren muss, da man sonst an den Rändern Artefakte hat (die logischerweise Teile der Hintergrundfarbe enthalten) die dann in der OpenGL-Anwendung zu unschönen Effekten führen. Um das zu verbildlichen hier nochmal unsere Panzertextur, allerdings begleitet vom (im Bildformat gespeichertem) Alphakanal:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_5.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links also unsere Textur und rechts der Alphakanal. Den sieht man normalerweise nicht, aber fast jedes Bildbearbeitungsprogramm gibt einem die Möglichkeit sich diesen anzeigen zu lassen. Wie zu sehen befinden sich in unserem Falle nur zwei Werte im Alphakanal. Und zwar Schwarz (= 0) für komplett transparent und Weiß (= 1) für komplett Sichtbar.&lt;br /&gt;
&lt;br /&gt;
Unter OpenGL nutzen wir jetzt für die Transparenz den [[GlAlphaFunc|Alphatest]]. Transparenz ließe sich auch über Blending realisieren, allerdings hat Blending den Nachteil das man dann die transparenten Objekte nach Tiefe sortieren müsste, da Blending im Framepuffer abläuft und nicht wie der Alphatest auf Fragmentbasis, wo wir uns dann keine Sorge um die Reihenfolge unserer Objekte machen müssen. Wollen wir nun also den Alphakanal der Textur nutzen (natürlich muss dieser vorher im Texturenloader geladen werden, sonst geht's nicht) müssen wir vor dem rendern des mit der Objekttextur belegten Quads den Alphatest aktiveren und festlegen wie der Test auszusehen hat :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_ALPHA_TEST);&lt;br /&gt;
glAlphaFunc(GL_GREATER, 0.1);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zuerst aktiveren wir also den Alphaest (dazu gibt es die Konstante '''GL_ALPHA_TEST'''), bevor wir dann der GL mittels [[GlAlphaFunc|glAphaFunc]] sagen wie der Test aussehen soll. Der erste Parameter ('''GL_GREATER''') gibt an, das nur Fragmente (also Teile der Textur) gerendert werden sollen deren Alphawert größer ist als der im zweiten Wert angegebene (0.1). Wie auch Farbwerte wird der Alphawert unter OpenGL &amp;quot;geclampt&amp;quot;, also in eine bestimmte Reichweite gebracht, nämlich 0 (= Schwarz) bis 1 (= Weiß). Die 0,1 (statt der 0) als Vergleichswert nehmen wir quasi aus Toleranz. Wenn wir das obige also getan haben, dürften wir auf unserem Quad (sofern der Alphakanal korrekt erstellt und geladen wurde) also nur noch das eigentliche Objekt sehen, und der Hintergrund müsste an den transparenten (Alpha &amp;lt;= 0,1) zu sehen sein:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_6.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir unsere Bohne ohne aktiven Alphatest, was zur Folge hat das der eigentlich transparente (schwarze) Teil der Objekttextur den Hintergrund überdeckt. Rechts wuede der Alphatest aktiviert und wir sehen nur den Teil unseres Objektes den wir auch sehen wollen.&lt;br /&gt;
&lt;br /&gt;
===Das Objekt anzeigen===&lt;br /&gt;
&lt;br /&gt;
Nachdem wir nun unsere Textur mit passendem Alphakanal geladen haben und den Alphatest auch aktiviert haben, müssen wir schlussendlich noch unser(e) Objekt(e) rendern. Wie schon mehrfach gesagt nutzen wir dazu die GL_QUADS-Primitive. Bei diesem Primitiventyp beschreiben wir mit vier Eckpunkten ein Rechteck (das von der Grafikkarte dann in zwei Dreiecke zerlegt wird), wobei jeder Eckpunkt auch eine Texturkoordinate zugewiesen bekommt. Diese Koordinate gibt an, aus welchem Teil der Textur dieser Eckpunkt seine Bilddaten beziehen soll, und sie wird über das gesamte Quad hinweg interpoliert. Also haben wir in der genauen Mitte des Quads als interpolierte Texturkoordinate das genaue Mittel der übergebenen Texturkoordinaten. Um diese Interpolation müssen wir uns allerdings keine Sorgen machen, das macht die Grafikkarte.&lt;br /&gt;
&lt;br /&gt;
Und in Sachen Texturkoordinaten sind wir auch schnell fertig, denn für den Anfang haben wir pro Textur immer nur ein Objekt (später zeige ich dann wie man mehrere Objekt in eine Textur packt) und müssen dementsprechend auch nur eine 1 (= Ende der Textur) bzw. 0 (= Anfang der Textur vergeben. Wenn man sich das bildlich vorstellt, sieht das dann so aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_7.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Da wir nur mit 2D-Texturen arbeiten, müssen wir pro Eckpunkt auch nur zwei Koordinaten angeben. Und zwar einmal in X-Richtung auf der Textur (unter OpenGL auch S-Richtung genannt, oft auch mit &amp;quot;U&amp;quot; betitelt) und in Y-Richtung (unter OpenGL T-Richtung, oft auch &amp;quot;V&amp;quot; genannt). Wenn S=0 und T=0, bedeutet das also das dieser Eckpunkt seinen [[Texel|Texel]] (wie Pixel, bloß im Bezug auf Texturen) aus der oberen linken Ecke unserer Textur (X=0/Y=0) bezieht, während S=1 und T=1 dafür sorgt das der Eckpunkt sich den Texel in der untersten rechten Ecke der Textur schnappt. Wie bereits oben erwähnt müssen wir uns um den Raum zwischen den vier Eckpunkten nicht kümmern, das wird ja von der Hardware linear interpoliert.&lt;br /&gt;
&lt;br /&gt;
Der Quellcode zu obigem Beispiel sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBegin(GL_QUADS);&lt;br /&gt;
 glTexCoord2f(0,0); glVertex3f(-Breite/2, -Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(1,0); glVertex3f(+Breite/2, -Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(1,1); glVertex3f(+Breite/2, +Höhe/2, -Tiefe);&lt;br /&gt;
 glTexCoord2f(0,1); glVertex3f(-Breite/2, +Höhe/2, -Tiefe);&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer obigen Text aufmerksam gelesen hat, sollte eigentlich problemlos verstehen was der Quellcode denn bewirkt. Wer damit Problem hat, der sollte sich das obige Kapitel nochmal unbedingt sorgfältig durchlesen, denn das ist eine sehr wichtige Sache.&lt;br /&gt;
&lt;br /&gt;
Soviel also zu den Grundlagen von 2D unter OpenGL. Wer nämlich hier angelangt ist, sollte zumindest 2D-Objekte unter OpenGL anzeigen können. Evtl. ist es hier angebracht das Tutorial einige Minuten ruhen zu lassen und ein wenig mit dem Erlerntem herumzuprobieren. Danach geht's nämlich mit etwas fortgeschritteneren (aus Sicht des Einsteigers) Themen weiter.&lt;br /&gt;
&lt;br /&gt;
===Die Rolle des Tiefenpuffers===&lt;br /&gt;
&lt;br /&gt;
Trotz der Tatsache dass wir in 2D die dritte Dimension vernachlässigen, bedeutet dies nicht das wir den Tiefenpuffer nicht doch nutzen können. Und zwar nutzen wir diesen in 2D zur hardwarebeschleunigten Sortierung unserer Objekte. In 2D-Anwendungen kann es ja genauso vorkommen das ein Objekt unter (&amp;quot;hinter&amp;quot;) einem anderen liegt und da wäre es ziemlich dumm diese selbst zu sortieren, wo OpenGL uns doch einen Tiefenpuffer anbietet der dies für uns macht.&lt;br /&gt;
&lt;br /&gt;
Genau deshalb haben wir mittels glOrtho auch die Reichweite für unseren Tiefenpuffer angegeben. Haben wir dann auch noch den Tiefentest mittels {{INLINE_CODE|glEnable(GL_DEPTH_TEST)}} und dem passenden Tiefentest via {{INLINE_CODE|[[glDepthFunc]](GL_LESS ''oder'' GL_EQUAL)}} aktiviert, so können wir über die Z-Koordinate unserer Objekte angeben wo die nun genau liegen. Ein Objekt dessen Z-Koordinate also näher an Z-Near ist, wird dann über einem an gleicher Stelle befindlichem Objekt mit einer Z-Koordinate näher an Z-Far gerendert, und zwar egal welches dieser Objekte wir als erstes an die GL übergeben haben.&lt;br /&gt;
&lt;br /&gt;
===Backface Culling===&lt;br /&gt;
&lt;br /&gt;
Auch diese von OpenGL angebotene Funktionalität sollte hier nicht verschwiegen werden. Denn in OpenGL bestehen Flächen immer aus einer Vorder- und Rückseite (wie im echten Leben, ein Blatt Papier hat ja auch zwei Seiten, egal wie dünn es ist), was spätestens dann Sinn macht wenn man bedenkt das man sich in einer 3D-Umgebung ja komplett frei bewegen kann. Doch in unserer 2D-Welt sehen wir immer nur eine Seite unserer Objekte, egal was wir anstellen. Und genau deshalb sollten wir OpenGLs [[Backface Culling]] (zu Deutsch heisst das wörtlich &amp;quot;Rückseiten Ausschluß&amp;quot;, aber solche Fachbegriffe deutsch man auch besser nicht ein) aktivieren, denn ist dies nicht der Fall, so werden alle Berechnungen immer für beide Seiten eines Polygons ausgeführt. Und dabei spielt es keine Rolle welche der Seiten sichtbar ist oder nicht. Wir aktivieren also das Backfaceculling und sagen OpenGL dass die Rückseiten der Primitiven nicht dargestellt werden soll (letzteres könnte man sich sparen, da das die Voreinstellung ist, allerdings sollte man lieber auf Nummer sicher gehen):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glEnable(GL_CULL_FACE);&lt;br /&gt;
glCullFace(GL_BACK);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solltet ihr jetzt übrigens eure Objekte nicht mehr sehen, dann habt ihr die Eckpunkte eurer Primitiven in der falschen Reihenfolge (Standard ist für OpenGL '''GL_CCW''' ('''C'''ounter'''C'''lock'''W'''ise, gegen den Uhrzeigersinn) angegeben. Ich empfehle dann entweder einen Blick ins Reedbook oder in eine der Beispielanwendungen, wo es eine Funktion namens ''DrawQuad'' gibt, die ein korrektes Quad rendert. Bei modernen Grafikkarten sollte das Backface Culling zwar nur recht wenig Performance bringen, aber es wäre trotzdem Performanceverschwendung dieses nette Feature einfach ungenutzt zu lassen.&lt;br /&gt;
&lt;br /&gt;
==Animation==&lt;br /&gt;
Bisher können wir zwar unsere 2D-Objekte mittels texturierter Quads auf dem Bildschirm darstellen, aber das ist natürlich noch recht statisch; und was wäre ein Computerspiel ohne Animationen? Und genau darum kümmern wir uns jetzt. Aber zuerst kurz zum Unterschied &amp;quot;Animation in 3D&amp;quot; und &amp;quot;Animation in 2D&amp;quot;. In 3D ist es normalerweise so, dass man ein 3D-Modell lädt und dann die einzelnen Teile des Modells animiert, sei dies über die GL-Befehle oder Animationsdaten im 3D-Format (Bones, Keyframes). Das bedeutet also das man in 3D quasi unendlich viele Freiheiten hat, denn man kann ja z.&amp;amp;nbsp;B. den Turm eines Panzers über [[glRotate]]f in jeden beliebigen Winkel bringen. In 2D ist das anders, denn da sind ja alle Grafiken vorgefertigt und werden nur abwechselnd auf unsere Quads geklebt. Würden wir dort also den Turm eines vorgefertigten Panzers rotieren lassen wollen, so müssten wir jeden Animationsframe vorfertigen und als Textur laden. Man muss sich also vorher Gedanken drüber machen ob 2D denn im Endeffekt wirklich weniger Aufwand bedeutet. Aber diese Entscheidung muss jeder für sich selbst fällen, weshalb wir uns nun zwei verschiedenen Animationsmöglichkeiten widmen werden.&lt;br /&gt;
&lt;br /&gt;
===Animation über Einzeltexturen===&lt;br /&gt;
''(Projektdatei : openGL2D_demo1)''&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_8.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Die wohl offensichtlichste (und auch einfachste) Art ein 2D-Objekt über Texturen zu animieren, ist über in einzelnen Texturen abgelegte Frames. Besonders aus einem 3D-Animationsprogramm (3D Studio, Maya) geht das besonders einfach. Denn diese Programme können eine Animation als Einzelbilder auf die Platte rendern. Dadurch hat man dann für eine Animation mit 60 Bildern 60 Texturen die dann einfach in ein Array geladen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;var&lt;br /&gt;
 Frame : array of glUInt;&lt;br /&gt;
&lt;br /&gt;
SetLength(Frame, NumFrames);&lt;br /&gt;
for i := 0 to NumFrames-1 do&lt;br /&gt;
 LoadTexture('animframe'+IntToStr(i)+'.tga', Frame[i], False);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das zu animierende Objekt verpasst man dabei mit einem Fließkommawert der den aktuell anzuzeigenden Frame darstellt, und erhöht diesen dann über die Zeit. Beim Rendern des Objektes nutzt man diesen Wert gerundeten (Indizes müssen ja Ganzzahlwerte sein) als Index in das Texturenarray:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D,Frame[Round(CurrentFrame)]);&lt;br /&gt;
...&lt;br /&gt;
CurrentFrame := CurrentFrame + 0.025 * TimeFactor;&lt;br /&gt;
if CurrentFrame &amp;gt; Length(Frame) then&lt;br /&gt;
 CurrentFrame := 0;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieser Methode ist das man diese Animationen direkt aus seinem 3D-Programm heraus speichern kann und das die Animationen quasi unendlich lange (wobei sowohl Speicherplatz als auch Speicherausbau der Grafikkarte hier limitierende Faktoren sind) sein können. Nachteil ist der hohe Speicherverbrauch, sowohl auf der Platte als auch im Grafikspeicher, sowie die Tatsache das man dann recht oft die Textur wechseln muss.&lt;br /&gt;
&lt;br /&gt;
===Animation in einer einzigen Textur===&lt;br /&gt;
''(Projektdatei: openGL2D_demo2)''&lt;br /&gt;
&lt;br /&gt;
Diese Art der Animation ist wie oben schon angedeutet recht speichersparend und vermindert auch die Zahl der Texturenwechsel. Allerdings ist sie auch aufwendiger zu implementieren und unterliegt einigen Einschränkungen die man bei der Erstellung der Animationstextur berücksichtigen sollte. Statt also jeden Frame der Animation in einer eigenen Datei (und damit später auch Textur, obwohl sich das natürlich auch kombinieren lässt) abzulegen, wird versucht bei dieser Animationsart alle Frames in einem Gitter auf einer Textur anzuordnen.&lt;br /&gt;
&lt;br /&gt;
Wenn man nicht noch mit der Erstellung komplexer Texturkoordinaten rumfuchteln will, dann sollte man drauf achten dass das gewählte Gitter so hoch wie breit ist und die Texturen an diesem Gitter ausgerichtet sind. So habe ich bei dieser Beispieltextur (bevor sie für das Tutorial etwas verkleinert wurde) die Frames in einem Raster von 256x256 Pixeln untergebracht.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Explosion_det.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Zu sehen sind hier alle Animationsframes einer Explosionstextur aus der Beispielanwendung. Diese wurd mit einem entsprechenden Tool generiert, aber kaum ein 3D-Porgramm kann Animationen direkt in eine einzelne Textur exportieren. Hier muss man sich dann mit passenden Plug-Ins oder Drittprogrammen aushelfen.&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Abspielen&amp;quot; dieser Animation ist nun recht einfach, denn wir erinnern uns ja daran das die Texturkoordinaten in OpenGL immer im Bereich 0 bis 1 liegen, unabhängig (es gibt Ausnahmen, aber interessiert hier nicht) von der Größe unserer Textur. Also müssen wir im Endeffekt nur wissen wie viele Spalten und Zeilen unsere Animationstextur enthält um für jeden Frame die passenden Texturkoordinaten errechnen zu können. Um es konkret zu machen nehmen wir obiges Beispiel. Es besteht aus drei Reihen und drei Spalten, wobei die Animationen von links nach rechts durchlaufen. Also bedeutet dies das unser erster Animationsframe bei S=0 / T=0 beginnt und bei S=1/4 / T=1/4 Ende, Frame 2 beginnt dann bei S=1/4 / T=0 und endet bei S=2/3 / T=1/4, usw. Dies zu errechnen sollte als keine Probleme bereiten, genauso wie das Rendern.&lt;br /&gt;
&lt;br /&gt;
Doch dürfen wir die Nachteile dieser Animationsart auch nicht verschweigen. Das es oft schwierig ist (wenn man die Objekte und Animationen sowieso von Hand zeichnet dann natürlich nicht) aus den Animationsframes eine einzelne Textur zu machen habe ich bereits gesagt, aber man muss auch wie immer auf die Hardwarelimitationen achten. Denn wenn man viele Animationen in einer Textur unterbringen will, wird diese oft recht groß und selbst auf modernen Karten sollte die Textur nicht größer als 2048x2048 Pixel sein. Wenn wir also ein Objekt der Größe 256x256 haben, bekommen wir im besten Falle (2048 wird auf älteren Karten entweder nicht machbar sein, deren Grafikkartenspeicher fast ganz aufbrauchen, oder zu langsam sein) 64 Animationsframes auf eine Textur. Alles darüber müsste man dann in eine weitere Textur auslagern, was den Verwaltungsaufwand stark erhöhen würde. Ausserdem muss man drauf achten, dass sich die Animationsframes nicht direkt berühren, also das zwischen einem sichtbarer Objektteil in Frame N mindestens ein Pixel Abstand zum sichtbaren Objektteil in Frame N+1 besteht. Denn dadurch das die Textur von OpenGL gefiltert wird, verlaufen Pixel die direkt aneinander liegen ineinander; wodurch dann unschöne Effekte entstehen. Ein weitere (allerdings nicht so gravierender) Nachteil ist die Tatsache dass man solche Animationen nicht über Texturenwiederholung mehrfach auf ein Objekt legen kann. Wenn man bei der erstgenannten Animationsart z.&amp;amp;nbsp;B. statt S=1/T=1 S=2/T=2 nutzt, dann wird dann Animation insgesamt viermal auf dem Quad wiederholt. Da man hier aber über die Texturkoordinaten quasi einen Frame aus der Textur herauspickt ist das nicht möglich, was im Normalfall aber kaum Gewicht haben sollte.&lt;br /&gt;
&lt;br /&gt;
===Rotation und Skalierung===&lt;br /&gt;
''(Projektdatei: openGL2D_demo3)''&lt;br /&gt;
&lt;br /&gt;
Wenn man alles selbst zeichnet (also z.&amp;amp;nbsp;B. mit der GDI arbeitet), dann hat man für die Rotation (oder Skalierung) eines Objektes im Normalfall nur zwei Möglichkeiten: Entweder man schreibt sich eigene Routinen die den Pixelsalat rotieren (was meist langsam ist, solange man es nicht in Assembler schreibt) oder man erstellt Bilddateien auf denen die Objekte schon vorrotiert sind. Erstere Methode ist wie gesagt langsam und sieht hässlich aus (es sei denn man filtert auch noch selbst) und die zweite Methode schränkt einen auf die vorberechneten Drehwinkel ein.&lt;br /&gt;
&lt;br /&gt;
Alle gerade genannten Probleme kann man unter OpenGL dank der hardwarebeschleunigung ad acta legen. Nicht nur dass man dank Hardware unendlich schnell rotieren kann, diese Rotation auch noch frei ist, nein, man bekommt sogar das Filtering dank Hardware umsonst:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_10.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links ist das um 15° gegenüber dem Ausgangsbild gedrehte Raumschiff ohne Filtering zu sehen. Gut ist hier die dadurch entstehende &amp;quot;Körnung&amp;quot; erkennbar, die in Bewegung noch sehr viel unschöner aussieht. Rechts sieht man das gleiche, diesmal allerdings mit Filtering. Der Unterschied dürfte direkt auffallen, und besonders auf hellen Hintergründen ist er noch frapierender. Natürlich sollte man die Grundlagen von OpenGL beherrschen um die Rotation korrekt anwenden zu können, denn folgender Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glRotatef(45, 0,0,1);&lt;br /&gt;
glTranslatef(320, 240, 0);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bewirkt etwas total anderes als folgender Code :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glTranslatef(320, 240, 0);&lt;br /&gt;
glRotatef(45, 0,0,1);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer sich die OpenGL-Grundlagen bereits angeeignet hat, der wird sicher schnell erkannt haben wo der Unterschied liegt. Denn in OpenGL bewegt man Objekte nicht direkt, sondern immer nur den Ursprung der Matrix. Ersterer Code rotiert also unsere Matrix um 45° und verschiebt diese dann um 320 Einheiten auf der X- und 240 auf der Y-Achse, was dazu führt das unser Objekt in einem recht großen Kreis um den Ursprung rotiert wird. Der zweite Codeschnippsel hingegen verschiebt unser Objekt an den Punkt 320/240 (in unserem Falle genau die Bildschirmmitte) und rotiert dann dort unser Objekt um die eigene Achse. Das ist auch der Rotationscode den wir im Normalfall nutzen um ein Objekt um sich selbst rotieren zu lassen. In unserer 2D-Anwendung müssen wir auch prinzipiell nur um die Z-Achse rotieren, denn die ragt in OpenGL &amp;quot;in&amp;quot; den Bildschirm hinein. Um das nachzuvollziehen einfach mal den rechten Arm grade ausstrecken und &amp;quot;um&amp;quot; den ausgestreckten Zeigefinger rotieren lassen. Euer Arm stellt dann in diesem Falle die Z-Achse dar.&lt;br /&gt;
&lt;br /&gt;
Das Skalieren eines Objektes gestaltet sich noch leichter, denn hier muss man nichts weiter machen als vor dem Rendern des Quads ein glScalef aufzurufen und diesem dann den Skalierungsfaktor (1=keine Skalierung) pro Achse zu übergeben. Da wir hier allerdings nur in 2D arbeiten sollten wir die Z-Skalierung immer bei 1 belassen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glScalef(2,2,1);&lt;br /&gt;
DrawQuad(0,0,0, 256,256);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obiger Quellcode zeichnet unser Objekt in der doppelten Größe (also statt 256x256 Einheiten 512x512 Einheiten groß). Über die Skalierung kann man schön in 2D einen Tiefeneffekt realisieren, zum Beispiel ein Raumschiff das mit einer Skalierung von 0,5 /0,5 / 1 auf einem Träger startet und dann zu Beginn des Levels langsam in Richtung 1 / 1 / 1 skaliert wird. Dadurch wird das Schiff größer und es entsteht beim Betrachter der Eindruck, das Schiff würde hinaufsteigen.&lt;br /&gt;
&lt;br /&gt;
==Scrollen und zoomen==&lt;br /&gt;
''(Projektdatei: openGL2D_demo4)''&lt;br /&gt;
&lt;br /&gt;
Selbst viele kommerzielle 3D-Spiele benötigen oft einen 2D-Teil um solche Sachen wie Übersichtskarten (man will ja gerne wissen wo man hin will) oder evtl. Credits und ähnliche größere 2D-Anzeigen zu tätigen, die oft den ganzen Bildschirm einnehmen oder gar größer sind. Besonders bei solchen Sachen wie z.&amp;amp;nbsp;B. einer großen Übersichtskarte (sei es nun die Strategiekarte für einen Schlachtplatz im Zweiten Weltkrieg, oder die Übersichtskarte eines Fantasyreiches) sind die Vorteile von OpenGL (wie an dem im Download enthaltenem Beispiel zu erkennen) gut ersichtlich. Das Scrollen wird durch einen einfachen Aufruf an [[glTranslate]]f erledigt (um die außerhalb des sichtbaren Bereichs liegenden Teile der Karte muss man sich dabei keine Sorgen machen), während man das vergrößern der Karte (~ zoomen) mit einem einfachem [[glScale]]f vollbringen kann.&lt;br /&gt;
&lt;br /&gt;
Und dank der Hardwarebeschleunigung wird diese Karte schneller angezeigt als man dies von Hand (oder über andere 2D-APIs je tun) könnte. Auf einer halbwegs modernen Grafikkarte sollten locker an die 1000 FpS drin sein.&lt;br /&gt;
&lt;br /&gt;
Nachdem man die Übersichtskarte geladen hat, gestaltet sich das Rendern selbiger als sehr einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBindTexture(GL_TEXTURE_2D, MapTex);&lt;br /&gt;
glTranslatef(MapPos.x, MapPos.y, 0);&lt;br /&gt;
glScalef(MapScale, MapScale, MapScale);&lt;br /&gt;
DrawQuad(0,0,0, MapSize.x,MapSize.y);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sieht schockierend einfach aus. Mehr braucht es nicht um eine Übersichtskarte zu scrollen und zu zoomen. Allerdings sollte man wie bereits einige Male erwähnt wurde auf die Hardwarelimiationen achten. Wenn die Übersichtskarte also allzu groß sein sollte, dann kann man diese ja ohne Probleme unterteilen und als mehrere Quads rendern. Außer der etwas abgeänderten Positionierung der einzelnen Kartenteile ändert sich aber am Grundprinzip nichts.&lt;br /&gt;
&lt;br /&gt;
==Tiling (Kachelung)==&lt;br /&gt;
''(Projektdatei: openGL2D_demo5)''&lt;br /&gt;
&lt;br /&gt;
Die oben genannte Technik mag zwar gut genug für statische Übersichtskarten sein, aber wenn man eine dynamische Karte aus der Vogelperspektive realisieren will, so kommt man mit einer riesigen vorgefertigten Textur nicht weit. Dafür gibt es dann aber eine Technik namens &amp;quot;Tiling&amp;quot;, was zu Deutsch so viel wie &amp;quot;Kachelung&amp;quot; heißt. Hier hat man ähnlich einem Schachbrett ein zweidimensionales Spielfeld das aus unterschiedlichen Kacheln besteht die als Texturen vorliegen. In einem zweidimensionalem Array wird dann für jedes Feld gespeichert welche Textur zu ihm gehört. Diese Technik ist immer noch recht weit verbreitet (zumindest im Hobbybereich) und für 2D-Spiele aus der Vogelperspektive recht gut geeignet, wobei hier der Großteil der Arbeit eher beim Grafiker als beim Programmierer liegt, denn da die Teils nur Vierecke darstellen müssen Übergänge von z.&amp;amp;nbsp;B. einem Terraintyp zum anderen in die Textur gezeichnet werden. &lt;br /&gt;
&lt;br /&gt;
Das Rendern eines solchen Spielfeldes gestaltet sich dabei sehr einfach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;for x := 0 to MapWidth-1 do&lt;br /&gt;
 for y := 0 to MapHeight-1 do&lt;br /&gt;
  begin&lt;br /&gt;
  glBindTexture(GL_TEXTURE_2D, MapTexture[Map[x,y]]);&lt;br /&gt;
  DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
  end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Allerdings ist obige Methode alles andere als optimiert. Das erste (und größte) Problem ist die Tatsache das unabhängig von aktuellen Betrachtungsposition immer die komplette Karte gerendert wird. Bei großen Karten (z.&amp;amp;nbsp;B. 128x128 Kacheln) gehen dann selbst moderne Karten in die Knie. Die Kacheln außerhalb des Sichtbereiches werden zwar von der Grafikkarte nicht gerendert (da sie außerhalb des Viewports liegen), aber müssen dennoch in jedem Frame über den Bus gesendet werden, genauso wie die Texturenwechsel in jedem Frame stattfinden müssen. Das erste Problem lässt sich recht schnell lösen, in dem wir einfach prüfen ob die aktuell zu rendernde Kachel auch im momentan sichtbarem Bereich liegt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glScalef(MapScale, MapScale, MapScale);&lt;br /&gt;
for x := 0 to High(Map) do&lt;br /&gt;
 for y := 0 to High(Map[x]) do&lt;br /&gt;
  if (MapPos.x + x*32 &amp;gt;= -16*MapScale) and (MapPos.x + x*32 &amp;lt;= SizeX/MapScale+16) and&lt;br /&gt;
     (MapPos.y + y*32 &amp;gt;= -16*MapScale) and (MapPos.y + y*32 &amp;lt;= SizeY/MapScale+16) then&lt;br /&gt;
      begin&lt;br /&gt;
      glBindTexture(GL_TEXTURE_2D, MapTex[Map[x,y]]);&lt;br /&gt;
      DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
      end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der If-Abfrage, die wir vor dem Rendern einer jeden Kachel machen, prüfen wir jetzt ganz einfach ob die aktuelle Kachel im Sichtfeld liegt. Da wir eine dynamische Karte haben und die Vorteile von OpenGL nutzen wollen, müssen wir bei dieser Abfrage natürlich auch den Zoomfaktor (''MapScale'') und das Scrolling (''MapPos'') mit einbeziehen.&lt;br /&gt;
&lt;br /&gt;
Dank dieser offensichtlichen Optimierung dürften wir jetzt einen starken Performancegewinn von mehreren hundert Prozent sehen, denn sehr viele Texturenwechsel fallen weg und es wird sehr viel weniger Geometrie über den Bus gesendet. Aber natürlich sind wir noch nicht am Ende der Fahnenstange angelangt, denn wie gesagt sind Texturenwechsel recht performancelastig. Also liegt es nahe diese zu optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;for t := 0 to High(MapTex) do&lt;br /&gt;
 begin&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, MapTex[t]);&lt;br /&gt;
 for x := 0 to High(Map) do&lt;br /&gt;
  for y := 0 to High(Map[x]) do&lt;br /&gt;
   if Map[x,y] = t then&lt;br /&gt;
    if (MapPos.x + x*32 &amp;gt;= -16*MapScale) and (MapPos.x + x*32 &amp;lt;= SizeX/MapScale+16) and&lt;br /&gt;
       (MapPos.y + y*32 &amp;gt;= -16*MapScale) and (MapPos.y + y*32 &amp;lt;= SizeY/MapScale+16) then&lt;br /&gt;
        DrawQuad(MapPos.x+x*32, MapPos.y+y*32, 0, 32,32);&lt;br /&gt;
 end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie zu sehen haben wir unsere Schleife etwas umgebaut. Wir gehen jetzt in der Hauptschleife durch alle unsere Kacheln (abgelegt in ''MapTex'') und dann für jede Kachel die komplette Karte in beide Dimensionen durch. So binden wir jede Texur nur einmal und rendern dann alle Kacheln die diese Textur nutzen. Das klingt erstmal so (zumindest vom Schleifenaufbau her) als würden wir hier Performance vernichten, denn schliesslich gehen wir jetzt nicht einmal die komplette Karte durch, sondern so viele Male wie wir Kacheltexturen haben. Allerdings ist es meistens so das der CPU-Overhead durch die zusätzlichen Schleifendurchläuft weniger kostet als uns die gesparten Texturenwechsel eingebracht haben. Im Normalfall (es gibt natürlich Situationen wo der CPU-Overhead zu groß wird, z.&amp;amp;nbsp;B. bei wirklich riesigen Karten) sollten wir auch durch diese Optimierung einen Performancezuwachs im zweistelligen Prozentbereich erkennen.&lt;br /&gt;
&lt;br /&gt;
So viel also zum Thema Kachelung. Besonders für kleinere Projekte ist diese Technik ein guter Start und vor allem ist diese Technik leicht umzusetzen. Ist natürlich nicht mehr zeitgemäß, aber bei den meisten Hobbyprojekten geht es ja eher um den Inhalt und nicht nur um das Äußere. &lt;br /&gt;
&lt;br /&gt;
==Spezialeffekte==&lt;br /&gt;
&lt;br /&gt;
Nach diesem langen Marsch sind wir jetzt so ziemlich mit allen im 2D-Bereich verwendeten Techniken durch und können uns nun einem interessanterem Kapitel zuwenden; den Spezialeffekten. Hier ist der eigenen Kreativität natürlich keine (oder kaum, je nach Hardware) Grenze gesetzt, weshalb ich nur einige häufig unter 2D genutzte Effekte erwähnen möchte.&lt;br /&gt;
&lt;br /&gt;
===Beleuchtung (&amp;quot;Per-Pixel&amp;quot;)===&lt;br /&gt;
''(Projektdatei: openGL2D_demo6)''&lt;br /&gt;
&lt;br /&gt;
Beleuchtung ist ja (auch wenn man das nicht so wahrnimmt, da es ja im echten Leben selbstverständlich ist) eine Sache die man in keinem Spiel vernachlässigen sollte. Ohne korrekte Beleuchtung geht viel Atmosphäre flöten, aber besonders in einer 3D-Umgebung ist korrektes Per-Pixel-Licht (die OpenGL-Beleuchtung arbeitet auf Vertexbasis) oft schwer zu implementieren (was dank Shader aber leichter geworden ist). In einer 2D-Umgebung ist das aber zum Glück sehr viel einfacher, denn dort haben wir z.&amp;amp;nbsp;B. im Falle einer 2D-Karte ja keine dritte Dimension um die wir uns kümmern müssten, müssen unsere Lichtquellen also nicht auf die Szene draufprojizieren.&lt;br /&gt;
&lt;br /&gt;
In 2D geht das also ganz einfach und wir machen die Beleuchtung bequem über eine Lichttextur in der die Intensität der Lichtquelle abgelegt ist. Für die Demo habe ich dazu einen einfachen radialen Verlauf gewählt, aber der Fantasie sind da keine Grenzen gesetzt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_12.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Farbinformationen speichern wir nicht in der Textur, denn wir wollen ja dynamisch bleiben und realisieren die Färbung des Lichtes später in unserem Programm über einen [[glColor]]3f  Aufruf. Bevor wir allerdings loslegen, sollten noch ein paar Kleinigkeiten im Bezug auf diese (einfache Form der) Beleuchtung geklärt werden. Damit wir unsere Szene mit einer solchen Textur &amp;quot;beleuchten&amp;quot; können, nutzen wir additives Blending. Das bedeutet also das wir zur Farbe im Framepuffer (der unsere Karte zeigt) den Farbwert in unserer Lichttextur addieren. Dort wo unsere Textur also komplett weiß ist, haben wir auf der Karte die volle Lichtfarbe. Blending hat aber einen Nachteil, der in 3D oft sehr viel Kopfzerbrechen macht, aber in 2D leicht gelöst werden kann: Blending arbeitet &amp;quot;auf&amp;quot; dem Framepuffer, was also bedeutet das OpenGL in diesem Falle nicht für uns sortiert. Wenn wir dann also eine Lichttextur rendern die nahe am Betrachter ist und dahinter (im Raum) eine zweite Lichttextur rendern die weiter entfernt ist, werden wir diese nicht sehen, da im Framepuffer bereits die erste Lichttextur &amp;quot;liegt&amp;quot; (sprich dort der Z-Wert der ersten Textur abgelegt wurde und die Fragmente der zweiten Textur deshalb aufgrund des Z-Tests verworfen werden). Das ist natürlich nicht korrekt, aber in 2D lässt sich dieses Problem mit dem passenden Tiefentest lösen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glDepthFunc(GL_ALWAYS);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Normalerweise sollte man diese Tiefenfunktion erst setzen bevor man die Lichtquellen zeichnet, sofern man vorher den Tiefenpuffer nutzen will um die Objekte auf seiner Karte in der Höhe zu sortieren. Denn wie der Name vermuten lässt bewirkt diese Form des Tiefentests das Fragmente (=&amp;quot;Pixel auf Probe&amp;quot;) immer rasterisiert werden, egal ob sie jetzt durch ein bereits im Frampuffer liegendes Fragment verdeckt werden würden oder nicht. Wenn wir mit diesem Tiefentest nun also zwei Lichtquellen übereinander rendern würden, werden diese korrekt angezeigt. Aber wie immer soll euch dieser etwas technisch klingende Text nicht aus dem Konzept bringen, weshalb ich dann hier folgende zwei Bilder reden lasse:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_13.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
Links sehen wir zwei sich überlappende Lichtquellen mit einem normalerweise verwendetem Tiefentest ('''GL_LEQUAL''' oder '''GL_LESS'''). Dass die grüne Lichtquelle die zweite verdeckt ist reiner Zufall und liegt wohl daran das diese als erstes gerendert wurde. Wie oben gesagt (vereinfacht) steht dann im Z-Puffer drin das an dieser Stelle (des grünen Lichtes) bereits ein Objekt im Z-Puffer liegt. Danach wird dann irgendwann die zweite (blaue) Lichtquelle gerendert, aber die Stellen an denen bereits steht dass dort im Z-Puffer ein Fragment liegt werden nicht mehr gerendert, aufgrund des Tiefentests. Das zweite Bild ist hingegen korrekt, einzig der Tiefentest wurde auf '''GL_ALWAYS''' umgestellt. Dann werden die mit der Lichttextur belegten Quads immer gezeichnet, egal ob sich an der Z-Position bereits ein Fragment befindet oder nicht, und bei Lichtquellen ist das reichlich egal welche zuerst gerendert wird. Denn ob ich jetzt Blau mit Grün addiere, oder Grün mit Blau ist egal, denn beides ergibt im Ende Türkis. Das dürfte dann hoffentlich verstanden worden sein, wenn nicht dann einfach mal das Beispielprogramm öffnen und den Tiefetest wie hier angesprochen ändern; Probieren geht je bekannter weise meist über Studieren.&lt;br /&gt;
&lt;br /&gt;
Abschließend auch noch kurz zum verwendeten Blendmodus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBlendFunc(GL_ONE, GL_ONE);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer sich schon mal ein wenig mit dem Thema Blending beschäftigt hat, wird schnell erkennen was hier abläuft. Sowohl der Quellfaktor als auch der Zielfaktor stehen auf '''GL_ONE''', was bedeutet dass bei unserer Blendoperation die bereits im Framepuffer befindliche Farbe mit der Farbe unseres Lichtes addiert wird (additives Blending genannt). Bei einer grünen Lichtquelle haben wir in der Mitte also RGB = 0/1/0 und wenn wir das dann auf einen Pixel legen würden der halb grau ist (RGB = 0,5/0,5/0,5) hätten wir als Ergebnis RGB = 0,5/1/0,5 (1+0,5 ist eigentlich 1,5 , aber OpenGL zwängt Farbwerte in den Bereich 0..1).&lt;br /&gt;
&lt;br /&gt;
===Texturenverläufe===&lt;br /&gt;
''(Projektdatei: openGL2D_demo7)''&lt;br /&gt;
&lt;br /&gt;
Im Kapitel &amp;quot;Kachelung&amp;quot; habe ich erwähnt, dass es eigentlich Aufgabe des Grafikers ist die Überläufe zwischen zwei unterschiedlichen Kacheln zu erstellen. Allerdings lässt sich das auch mit OpenGL bewerkstelligen, und zwar dank Blending und des Alphakanals. Dazu rendern wir zuerst ein Quad mit der ersten Kachel, und zwar dort wo diese Kachel komplett erscheinen soll mit vollem Alpha (vierter Parameter von [[glColor]]4f = 1) und dort wo später die andere Kachel komplett erscheinen soll mit Alpha = 0. Danach rendern wir an exakt der gleichen Stelle die zweite Kachel, müssen aber natürlich darauf achten das wir den richtigen Tiefentest aktiviert haben damit diese auch sichtbar ist ('''GL_ALWAYS''' oder '''GL_LEQUAL'''), allerdings mit genau umgekehrten Alphawerten und aktiviertem Blending. Fürs Blending nutzen wir als Quellfaktor '''GL_SRC_ALPHA''' und als Zielfaktor dann in logischer Konsequenz '''GL_DST_ALPHA'''. Dadurch wird dann im finalen Ergebnis dort wo die erste Kachel eine Alpha von 1 hat ihr kompletter Farbwert übernommen und dort wo die zweite Kachel einen Alpha von 1 hat deren voller Farbwert. Dazwischen wird in gewohnter Weise interpoliert:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glDisable(GL_BLEND);&lt;br /&gt;
glBindTexture(GL_TEXTURE_2D, TileA);&lt;br /&gt;
glBegin(gl_Quads);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(0,0); glVertex3f(-128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(1,0); glVertex3f( 128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(1,1); glvertex3f( 128,  128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(0,1); glvertex3f(-128,  128, 0);&lt;br /&gt;
glEnd;&lt;br /&gt;
&lt;br /&gt;
glEnable(GL_BLEND);&lt;br /&gt;
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);&lt;br /&gt;
glBindTexture(GL_TEXTURE_2D, TileB);&lt;br /&gt;
glBegin(gl_Quads);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(0,0); glVertex3f(-128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(1,0); glVertex3f( 128, -128, 0);&lt;br /&gt;
 glColor4f(1,1,1,1); glTexCoord2f(1,1); glVertex3f( 128,  128, 0);&lt;br /&gt;
 glColor4f(1,1,1,0); glTexCoord2f(0,1); glVertex3f(-128,  128, 0);&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Allerdings wird das bei komplexeren Kachelübergängen recht aufwendig und endet in jeder Menge Overdraw, da man dann viele Übergänge rendern muss. Aber wer sich mal näher damit beschäftigen will, sollte einen Blick auf das &amp;quot;Verblendet&amp;quot;-Tutorial (Einsteiger) von Phobeus werfen, in dem auch diese Technik hier näher besprochen wird.&lt;br /&gt;
&lt;br /&gt;
===Schatten===&lt;br /&gt;
''(Projektdatei : openGL2D_demo8)''&lt;br /&gt;
&lt;br /&gt;
Im 3D-Bereich sind Schatten eigentlich immer noch die &amp;quot;Königsdisziplin&amp;quot; für jeden Programmierer, besonders wenn diese volumetrisch und vor allem auch korrekt sein sollen. Meist muss man dazu die Szene analysieren, Umrisse von 3D-Objekten generieren und auch noch diverse Spezialfälle beachten (Stichwort &amp;quot;Betrachter im Schattenvolumen&amp;quot;). In unserer heilen 2D-Welt geht das aber schon wie bei der Beleuchtung sehr viel einfacher und hat mit dreidimensionalen Schatten rein gar nichts gemeinsam.&lt;br /&gt;
&lt;br /&gt;
Hier gehen wir nämlich ganz einfach hin und täuschen Schatten vor indem wir unser Objekt (das dazu natürlich einen Alphakanal besitzen muss) mittels {{INLINE_CODE|glColor3f(0, 0, 0)}} schwarz machen und dann unter dem eigentlichen Objekt leicht versetzt (die Richtung des Versatzes kann man je nach Lichteinfall verändern) rendern. Über [[glScalef]] passen wir dann noch die Größe des Schattens an um einfach vermitteln zu können wie hoch sich unser Objekt befindet. Wenn wir also den Schatten eines Spielers rendern, dann kann der genauso groß sein wie der Spieler selbst, aber bei einem Flugzeug das hoch über dem Boden fliegt sollte der Schatten schon etwas verkleinert werden um einen Eindruck von der Flughöhe zu vermitteln.&lt;br /&gt;
&lt;br /&gt;
Rein programmiertechnisch sind Schatten in 2D (auch wenn diese keineswegs physikalisch korrekt sind) also genau das Gegenteil von 3D-Schatten: Einfach und ohne jegliche Hindernisse:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glPushMatrix;&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, ShipTex);&lt;br /&gt;
 glEnable(GL_ALPHA_TEST);&lt;br /&gt;
 glAlphaFunc(GL_GREATER, 0.1);&lt;br /&gt;
 glScalef(0.75, 0.75, 0.75);&lt;br /&gt;
 glColor3f(0, 0, 0);&lt;br /&gt;
 DrawQuad(60,-60,1, 256,192);&lt;br /&gt;
glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
glPushMatrix;&lt;br /&gt;
 glColor3f(1, 1, 1);&lt;br /&gt;
 glBindTexture(GL_TEXTURE_2D, ShipTex);&lt;br /&gt;
 glEnable(GL_ALPHA_TEST);&lt;br /&gt;
 glAlphaFunc(GL_GREATER, 0.1);&lt;br /&gt;
 DrawQuad(0,0,0, 256,192);&lt;br /&gt;
glPopMatrix;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im ersten Block rendern wir unser Objekt etwas verkleinert und nach unten/rechts versetzt, natürlich komplett schwarz. Danach müssen wir nur noch unser Objekt drüberrendern (in gewohnter Weise) und fertig ist unser Schatten:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutorial_2D_illustration_14.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
==Schlusswort==&lt;br /&gt;
&lt;br /&gt;
Das war es also zum Thema 2D in OpenGL. Ich hoffe stark das dieser doch recht ausführliche Bericht so ziemlich alle Bereiche abgedeckt hat und damit auch häufig gestellte Fragen beantwortet. Natürlich war das nicht alles was in diesem Bereich machbar ist, allerdings kann ich hier schlecht auf jeden Effekt eingehen, denn sonst könnte ich das Tutorial gleich als ein einige hundert Seiten starkes Buch verkaufen.&lt;br /&gt;
&lt;br /&gt;
Doch eines sei noch am Schluss gesagt: 2D ist zwar programmiertechnisch fast immer (besonders bei in 3D komplexen Sachen wie Beleuchtung und Schatten) sehr viel einfacher und man kommt dann auch meist schneller ans Ziel, allerdings ist hier die Erstellung des Inhalts meist aufwendiger. Während z.&amp;amp;nbsp;B. ein 3D-Terrain zwar von der Programmierung her aufwendiger ist, muss man dort am Ende nur eine Terraintextur draufkleben und fertig ist die Sache. In 2D muss man dies hingegen über Kacheln lösen und dann für jeden Übergang verschiedene Kacheln in einem Bildbearbeitungsprogramm erstellen. Oder zum Beispiel das in unserem letzten Beispiel verwendete Raumschiff; wenn man das in 3D über ein 3D-Modell animiert (Keyframes), dann ist es kaum Aufwand was am Modell zu verändern (andere Textur, Form ändern), aber in 2D liegen diese Animationen vorberechnet auf der Platte, und sobald man dann was am Raumschiff ändert, müssen auch alle Animationen geändert werden.&lt;br /&gt;
&lt;br /&gt;
Wie so oft im Leben muss man also abwägen was jetzt für die eigene Anwendung richtig ist. Essentiell reicht es sich die Frage ''&amp;quot;Ist es für mich aufwendiger in die 3D-Programmierung einzusteigen, oder es ist es aufwendiger den Content für meine 2D-Anwendung zu erstellen&amp;quot;'' zu beantworten, aber das kann ich euch nicht abnehmen, da müsst ihr selbst drauf antworten können. Außerdem sei noch gesagt das die moderne Generation der Computerspieler inzwischen 3D gewohnt ist, was dazu führt das 2D-Anwendungen dann spielerisch sehr überzeugen müssen.&lt;br /&gt;
&lt;br /&gt;
In dem Sinne also viel Spaß in der zweiten Dimension (die auch Spaß machen) kann. Und vergesst nicht: Ich WILL Feedback zu diesem Tutorial und außerdem will das DGL-Team sehen was ihr so mit unseren Tutorials auf die Beine stellt. Wenn dabei also was halbwegs brauchbares raus gekommen ist, lasst es uns wissen!&lt;br /&gt;
&lt;br /&gt;
Euer&lt;br /&gt;
:'''Sascha Willems''' (webmaster AT delphigl.de)&lt;br /&gt;
&lt;br /&gt;
== Dateien ==&lt;br /&gt;
* {{ArchivLink|file=tut_opengl2d_vcl|text=Delphi-VCL-Quelltexte und Windows-Binaries zum Tutorial}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|[[Tutorial Lektion 8]]|[[Tutorial_Matrix2]]}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorial|2D]]&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24573</id>
		<title>HUD</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24573"/>
				<updated>2010-01-12T13:51:09Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: /* Kritik */  erweitert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein '''Heads Up Display''' ist eine Anzeige welche ins Sichtfeld des Nutzers eingeblendet wird.&lt;br /&gt;
&lt;br /&gt;
==Herkunft==&lt;br /&gt;
Ursprünglich stammt das HUD aus der Luftwaffe, wo es schon seit ca. den 70er Jahren eingesetzt wird um wichtige Informationen direkt im Blickfeld des Piloten anzuzeigen. Dies geschieht entweder über ein Display am Helm (daher auch &amp;quot;Heads up display&amp;quot;) oder (neuer) durch Projektion der Daten auf die Scheibe des Cockpits selbst. So muss der Pilot seinen Blick nicht vom wichtigen Kampfgeschehen abwenden sondern kann sich auf dass konzentrieren was um ihn rum geschieht, im Gegensatz zu alten Flugzeugen, bei denen der Pilot permanent alle möglichen Instrumente im Auge behalten musste.&lt;br /&gt;
&lt;br /&gt;
Inzwischen findet diese Technik auch Verwendung in Fahrzeugen, momentan allerdings eher in der gehobenen Klasse (die Dodge Viper besitzt z.B. ein zuätzliches HUD mit Geschwindigkeit, Gang, Drezhal, dass auf die Scheibe über dem Lenkrad projeziert wird).&lt;br /&gt;
&lt;br /&gt;
==Verwendung==&lt;br /&gt;
Da man bei Videospielen oder anderen 3D-Anwendungen fast immer den kompletten Bildschirm im Blickfeld hat, hat sich der Begriff HUD hier auch schnell eingebürgert und wird hier für fast alle Anwendungsgebiete verwendet, egal ob man in einem Jump'n'Run nur Leben und Punkte anzeigt oder in einer komplexen Simulation ein echtes HUD emuliert.&lt;br /&gt;
&lt;br /&gt;
Allerdings spricht man eigentlich nur in Actionspielen und Simulationen von einem HUD. Damit ist dann eine Anzeige gemeint die permanent die gleichen Informationen anzeigt und dabei nur wenige Elemente besitzt. Bei einem Strategiespiel, dass sehr viele Informationen anzeigt und zusätzlich noch Fenster oder weitere Bildschirme mit mehr Informationsmaterial anzeigt, spricht man daher nicht mehr von einem HUD, sondern von einer [[GUI]] (Graphical User Interface - Grafische Benutzerschnittstelle).&lt;br /&gt;
&lt;br /&gt;
==Realisierung==&lt;br /&gt;
HUDs werden üblicherweise im [[glOrtho|Othogonal/2D-Modus]] realisiert. Es gibt natürlich auch Ausnahmen, da es hier keinerlei feste Definitionen gibt. In Flugsimulatoren z.B. wird das HUD natürlich wie in der Realität auf z.B. die dreidimensionale Oberfläche des Cockpits projeziert, nachdem es üblicherweise in eine Textur gerendert wurde.&lt;br /&gt;
&lt;br /&gt;
==Kritik und Alternativen==&lt;br /&gt;
Ein HUD ist immer etwas nützliches. Allerdings wiederstrebt die Darstellung der typischen Elemente eines HUDs oft dem Trend des fortschreitenden Realismus, denn in der Realität besitzt man ja auch keine Statusanzeien über seine eigene Lebensenergie o.ä. Daher gibt es hier diverse Entwickler die versuchen ein normales HUD zu vermeiden um den Spieler nicht mit realitätsfremden Einblendungen aus der Immersion zu reissen. Ein sehr gutes und aktuelles Beispiel ist der Titel Dead Space, bei dem man kein typisches HUD mehr anzeigt. Stattdessen werden alle wichtigen Informationen direkt auf den Objekten angezeigt. Lebensnergie wird über einen blauen Schlauch am Rücken der Spielfigur dargestellt, während der Munitonsvorrat direkt an der Waffe ersichtlich ist (je nach Modell unterschiedlich). Dies ermöglicht die Anzeige wichtiger Informationen ohne den Spieler über ein entfremdendes HUD aus der Atmosphäre zu reissen. Diesen Ansatz verfolgen auch andere Spielentwickler, und er dürfte in Zukunt mehr an Bedeutung gewinnen. &lt;br /&gt;
&lt;br /&gt;
[[Datei:hud_deadspace.jpg]]&lt;br /&gt;
&lt;br /&gt;
Es gibt natürlich weitere Beispiele für Statusinformationen die man ohne HUD darstellen kann. Darunter fallen z.B. Waffenmagazine um den Spieler über seinen Munitionsstand zu informieren. Hier gibt es Waffen bei denen man dies direkt erkennen kann (z.B. die FN P90) oder Spiele bei denen man per Tastendruck das Magazin einer Waffe prüfen kann (z.B. bei einem Horroshooter von Sega, der als Beispiel hier nicht aufgeführt werden darf da er in Deutschland verboten wurde). Inzwischen hat es sich zumindest bei Shootern auch durchgesetzt dass man keine traditionelle Anzeige der Lebensenergie mehr hat, sondern direkt z.B. über einen sich dunkelrot färbenden Bildschirm über den aktuellen Gesundheitszustand informiert wird. &lt;br /&gt;
&lt;br /&gt;
Natürlich kann man Statusinformationen auch über den Ton &amp;quot;darstellen&amp;quot;, also z.B. auf welchem Untergrund man sich bewegt und wie leicht man dadurch hörbar ist (sehr gut in &amp;quot;Rainbow Six : Ravenshield (©Ubisoft)&amp;quot; implementiert, so gut dass man über die Schrittgeräusche und deren Dämpfung etc. ein Spiel gewinnen kann), oder auch durch Herzklopfen, welches angibt wie schwer der Charakter verletzt ist. Hier ist es natürlich etwas schwerer als über den optischen weg, da der Spieler erstmal erkennen muss wann genau welcher Ton welchen Zustand darstellt. &lt;br /&gt;
&lt;br /&gt;
Aber eine Kombination aus optischem und akkustischem Feedback kann fast immer ein typisches HUD erstezen und trägt stark zur Steigerung der Spielatmosphäre bei.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Kompromiss der häufig Anwendung findet ist übrigens das temporäre Ausblenden des HUDs. So kann man z.B. Lebensnergie usw. ausblenden wenn sich der Charakter nicht im Kampf befindet.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
[[Datei:hud_jagdgeschwader.jpg]] [[Datei:hud_cardemo.jpg]]&lt;br /&gt;
&lt;br /&gt;
Links das Bild eines HUDs aus dem Spiel &amp;quot;Jagdgeschwader&amp;quot;, einem Arcadeflugspiel. Dort ist das HUD unterteilt, und zeigt neben den verbleibenden Leben eine rotierende Karte mit Gegner- und Spielerposition und weiteren wichtigen Items, sowie (links unten) Statusinformationen zum Flugzeug des Spielers (Lebensenergie, Temperatur der Waffen und Geschwindigkeit).&lt;br /&gt;
&lt;br /&gt;
Rechts davon ein &amp;quot;kombiniertes&amp;quot; HUD, das alle wichtigen Informationen in einem Bildschirmabschnitt unterbrint. Da es sich hier um eine Fahrzeugdemo handelt ist dieses HUD der Anzeigetafel eines typischen Autos nachempfunden und beinhaltet typische Elemente wie Drezahlmesser, Tacho und Ganganzeige.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24572</id>
		<title>HUD</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=HUD&amp;diff=24572"/>
				<updated>2010-01-12T13:37:14Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: Beispielbilder, Erklärung und erweitert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein '''Heads Up Display''' ist eine Anzeige welche ins Sichtfeld des Nutzers eingeblendet wird.&lt;br /&gt;
&lt;br /&gt;
==Herkunft==&lt;br /&gt;
Ursprünglich stammt das HUD aus der Luftwaffe, wo es schon seit ca. den 70er Jahren eingesetzt wird um wichtige Informationen direkt im Blickfeld des Piloten anzuzeigen. Dies geschieht entweder über ein Display am Helm (daher auch &amp;quot;Heads up display&amp;quot;) oder (neuer) durch Projektion der Daten auf die Scheibe des Cockpits selbst. So muss der Pilot seinen Blick nicht vom wichtigen Kampfgeschehen abwenden sondern kann sich auf dass konzentrieren was um ihn rum geschieht, im Gegensatz zu alten Flugzeugen, bei denen der Pilot permanent alle möglichen Instrumente im Auge behalten musste.&lt;br /&gt;
&lt;br /&gt;
Inzwischen findet diese Technik auch Verwendung in Fahrzeugen, momentan allerdings eher in der gehobenen Klasse (die Dodge Viper besitzt z.B. ein zuätzliches HUD mit Geschwindigkeit, Gang, Drezhal, dass auf die Scheibe über dem Lenkrad projeziert wird).&lt;br /&gt;
&lt;br /&gt;
==Verwendung==&lt;br /&gt;
Da man bei Videospielen oder anderen 3D-Anwendungen fast immer den kompletten Bildschirm im Blickfeld hat, hat sich der Begriff HUD hier auch schnell eingebürgert und wird hier für fast alle Anwendungsgebiete verwendet, egal ob man in einem Jump'n'Run nur Leben und Punkte anzeigt oder in einer komplexen Simulation ein echtes HUD emuliert.&lt;br /&gt;
&lt;br /&gt;
Allerdings spricht man eigentlich nur in Actionspielen und Simulationen von einem HUD. Damit ist dann eine Anzeige gemeint die permanent die gleichen Informationen anzeigt und dabei nur wenige Elemente besitzt. Bei einem Strategiespiel, dass sehr viele Informationen anzeigt und zusätzlich noch Fenster oder weitere Bildschirme mit mehr Informationsmaterial anzeigt, spricht man daher nicht mehr von einem HUD, sondern von einer [[GUI]] (Graphical User Interface - Grafische Benutzerschnittstelle).&lt;br /&gt;
&lt;br /&gt;
==Realisierung==&lt;br /&gt;
HUDs werden üblicherweise im [[glOrtho|Othogonal/2D-Modus]] realisiert. Es gibt natürlich auch Ausnahmen, da es hier keinerlei feste Definitionen gibt. In Flugsimulatoren z.B. wird das HUD natürlich wie in der Realität auf z.B. die dreidimensionale Oberfläche des Cockpits projeziert, nachdem es üblicherweise in eine Textur gerendert wurde.&lt;br /&gt;
&lt;br /&gt;
==Kritik==&lt;br /&gt;
Ein HUD ist immer etwas nützliches. Allerdings wiederstrebt die Darstellung der typischen Elemente eines HUDs oft dem Trend des fortschreitenden Realismus, denn in der Realität besitzt man ja auch keine Statusanzeien über seine eigene Lebensenergie o.ä. Daher gibt es hier diverse Entwickler die versuchen ein normales HUD zu vermeiden um den Spieler nicht mit realitätsfremden Einblendungen aus der Immersion zu reissen. Ein sehr gutes und aktuelles Beispiel ist der Titel Dead Space, bei dem man kein typisches HUD mehr anzeigt. Stattdessen werden alle wichtigen Informationen direkt auf den Objekten angezeigt. Lebensnergie wird über einen blauen Schlauch am Rücken der Spielfigur dargestellt, während der Munitonsvorrat direkt an der Waffe ersichtlich ist (je nach Modell unterschiedlich). Dies ermöglicht die Anzeige wichtiger Informationen ohne den Spieler über ein entfremdendes HUD aus der Atmosphäre zu reissen. Diesen Ansatz verfolgen auch andere Spielentwickler, und er dürfte in Zukunt mehr an Bedeutung gewinnen.&lt;br /&gt;
&lt;br /&gt;
[[Datei:hud_deadspace.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
[[Datei:hud_jagdgeschwader.jpg]] [[Datei:hud_cardemo.jpg]]&lt;br /&gt;
&lt;br /&gt;
Links das Bild eines HUDs aus dem Spiel &amp;quot;Jagdgeschwader&amp;quot;, einem Arcadeflugspiel. Dort ist das HUD unterteilt, und zeigt neben den verbleibenden Leben eine rotierende Karte mit Gegner- und Spielerposition und weiteren wichtigen Items, sowie (links unten) Statusinformationen zum Flugzeug des Spielers (Lebensenergie, Temperatur der Waffen und Geschwindigkeit).&lt;br /&gt;
&lt;br /&gt;
Rechts davon ein &amp;quot;kombiniertes&amp;quot; HUD, das alle wichtigen Informationen in einem Bildschirmabschnitt unterbrint. Da es sich hier um eine Fahrzeugdemo handelt ist dieses HUD der Anzeigetafel eines typischen Autos nachempfunden und beinhaltet typische Elemente wie Drezahlmesser, Tacho und Ganganzeige.&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:hud_deadspace.jpg&amp;diff=24571</id>
		<title>Datei:hud deadspace.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:hud_deadspace.jpg&amp;diff=24571"/>
				<updated>2010-01-12T13:36:34Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: HUD des Spiels Dead Space (© 2008 Electronic Arts)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;HUD des Spiels Dead Space (© 2008 Electronic Arts)&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Datei:hud_cardemo.jpg&amp;diff=24570</id>
		<title>Datei:hud cardemo.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Datei:hud_cardemo.jpg&amp;diff=24570"/>
				<updated>2010-01-12T13:14:14Z</updated>
		
		<summary type="html">&lt;p&gt;Sascha willems: HUD für meine Newton-Fahrzeugdemo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;HUD für meine Newton-Fahrzeugdemo&lt;/div&gt;</summary>
		<author><name>Sascha willems</name></author>	</entry>

	</feed>