<?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=Lossy+eX</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=Lossy+eX"/>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php/Spezial:Beitr%C3%A4ge/Lossy_eX"/>
		<updated>2026-05-29T16:48:34Z</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=24182</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=24182"/>
				<updated>2009-09-14T08:31:12Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &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;
&amp;lt;/pascal&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Team&amp;diff=24168</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Team&amp;diff=24168"/>
				<updated>2009-08-27T07:29:40Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* 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:Lossy eX|Lossy eX]] &lt;br /&gt;
|{{eMail|Lossy|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*dglOpenGL.pas&lt;br /&gt;
*Tutorial Lektor&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;
*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;
|-&lt;br /&gt;
|[[Benutzer:Lord_Horazont|Lord Horazont]] &lt;br /&gt;
| -&lt;br /&gt;
|&lt;br /&gt;
*SVN/WebSVN Betreuung&lt;br /&gt;
*News eintragen&lt;br /&gt;
*allgemeine inhaltliche Kontrolle&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;
| -&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;
| -&lt;br /&gt;
|&lt;br /&gt;
*Filesektion (SVN Betreuung)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=GL_ARB_texture_env_combine&amp;diff=20982</id>
		<title>GL ARB texture env combine</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=GL_ARB_texture_env_combine&amp;diff=20982"/>
				<updated>2007-11-03T11:05:35Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Verwendungsbeispiel  */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= GL_ARB_texture_env_combine =&lt;br /&gt;
{{Hinweis|Die Orginalspezifikation finden Sie unter &amp;quot;Ressourcen&amp;quot; am Ende des Artikels.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Abfragestring ==&lt;br /&gt;
GL_ARB_texture_env_combine&lt;br /&gt;
&lt;br /&gt;
== Abhängigkeiten ==&lt;br /&gt;
Diese Extension baut auf OpenGL 1.1 auf und ist abhängig von der OpenGL 1.2.1 Extension [[GL_ARB_multitexture]].&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Diese Extension ist eine wichtige Erweiterung für [[Multitexturing]]. Sie erlaubt es zu bestimmen wie die Farbwerte und Alphawerte von 2 oder mehreren Texturen kombiniert werden soll.&lt;br /&gt;
&lt;br /&gt;
Für jede [[Texture stage]] können hierbei die Berechnung die durchgeführt werden sollen angegeben werden. Zuerst wird die Berechnung für die 0. [[Texture stage]] durchgeführt, dann die Berechnungen für die 1. und so weiter, bis die letzte [[Texture stage]] das Ergebnis an die nächste Stufe der [[Rendering Pipeline]] weiter gibt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Verwendung''' ===&lt;br /&gt;
Man muss OpenGL für jede [[Texture stage]] mitteilen, dass diese Extension verwendet werden soll. Dies wird mittels&lt;br /&gt;
&lt;br /&gt;
[[glTexEnv|glTexEnvi]]( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);&lt;br /&gt;
&lt;br /&gt;
gemacht. Nun muss sowohl für den Alphawert, als auch für den Farbwert festgelegt werden, welcher Art die Kombinierung sein soll.&lt;br /&gt;
&lt;br /&gt;
=== '''Kombinierungsarten''' ===&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Art'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Formel'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_REPLACE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_MODULATE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 * Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ADD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 + Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ADD_SIGNED_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 + Arg1 - 0.5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SUBTRACT_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 - Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_INTERPOLATE_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 * (Arg2) + Arg1 * (1-Arg2)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gesetzt wird die Kombinierungsart mittels: &lt;br /&gt;
&lt;br /&gt;
[[glTexEnv|glTexEnvi]]( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, KOMBINIERUNGSART);&lt;br /&gt;
&lt;br /&gt;
für die Farbwerte bzw. mit&lt;br /&gt;
&lt;br /&gt;
[[glTexEnv|glTexEnvi]]( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, KOMBINIERUNGSART);&lt;br /&gt;
&lt;br /&gt;
für die Alphawerte. Nun müssen noch die Operanden Arg0, Arg1 und Arg2 für die Kombinierung gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Operanden''' ===&lt;br /&gt;
Für das setzen eines Operanden werden 2 Informationen benötigt. Zum einen die Quelle (Source) der Information, wofür es folgende Möglichkeiten gibt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Quelle'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Beschreibung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_PRIMARY_COLOR_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Farbwert der mit [[glColor]] oder vergleichbarem gesetzt wurde.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_TEXTURE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert der aktuellen [[Textur]] (in der aktuellen [[Texture stage]])&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_CONSTANT_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert der mit [[glTexEnv]]fv] für die aktuelle [[Textur]] gesetzt wurde.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_PREVIOUS_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Ergebnis der Berechnungen aus der vorherigen [[Texture stage]], oder gleich wie GL_PRIMARY_COLOR_ARB, wenn es sich um die aller erste [[Texture stage]] handelt.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
nun erfolgt noch die Unterscheidung für welchen Operanden (Arg0, Arg1 oder Arg2) der Wert gesetzt werden soll, und ob dieser Operand für die RGB- oder Alphawert Berechnung verwendet werden soll. Hier gibt es folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Art der Quelle'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Beschreibung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg0 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg1 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg2 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg0 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg1 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Wert für Arg2 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gesetzt werden diese Werte nun mit&lt;br /&gt;
&lt;br /&gt;
[[glTexEnv|glTexEnvi]]( GL_TEXTURE_ENV, Art der Quelle, Quelle );&lt;br /&gt;
&lt;br /&gt;
Nun weiß OpenGL welchen Wert er für die Berechnung nehmen soll, jedoch muss man auch noch angeben Welcher Teil des Wertes verwendet werden soll. Für die RGB Berechnung hat man hier folgende Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Operand RGB-Berechnung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Beschreibung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SRC_COLOR'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende RGB Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_COLOR'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende 1-RGB Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende Alpha Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende 1-Alpha Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da RGB 3 Werte sind und Alpha nur 1 Wert gibt es für die Alphaberechnung nur 2 Arten von Operanden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Operand Alphaberechnung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Beschreibung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende Alpha Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Verwende 1-Alpha Teil des Wertes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um anzugeben wofür der Operand eingesetzt werden soll muss man noch wählen zwischen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Art des Operanden'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Beschreibung'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg0 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg1 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg2 in der RGB Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg0 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg1 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Operand für Arg2 in der Alpha Berechnung setzen&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gesetzt werden diese Werte nun mit&amp;lt;br&amp;gt;[[glTexEnv]]i]( GL_TEXTURE_ENV, Art des Operanden, Operand Alphaberechnung bzw. Operand RGB-Berechnung );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Scalen''' ===&lt;br /&gt;
Am Ende der Berechnung einer [[Texture stage]] kann der errechnete Wert noch mit einem Scale Faktor multipliziert werden, und zwar mittels&lt;br /&gt;
&lt;br /&gt;
[[glTexEnv|glTexEnvf]]( GL_TEXTURE_ENV, RGB_SCALE_ARB, Faktor );&lt;br /&gt;
&lt;br /&gt;
Gültige Werte für Faktor sind hier jedoch nur 1.0, 2.0 oder 4.0. Am Ende Wird das Ergebnis noch auf den Wertebereich [0|1] gebracht. Zu hohe oder zu niedrige Werte werden mit 1.0 bzw. mit 0.0 ersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Neue Tokens ==&lt;br /&gt;
&lt;br /&gt;
=== Neue Parameterwerte ===&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_TEXTURE_ENV_MODE''' ist, dann ist für ''param'' folgender zustäzlicher Wert gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_COMBINE_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8570&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Diese Extension wird für diese [[Texture stage]] aktiviert&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''target'' '''TEXTURE_ENV''' ist, dann sind für ''pname'' folgende zustäzliche Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_COMBINE_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8571&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Berechnungsart für RGB angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_COMBINE_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8572&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Berechnungsart für Alpha angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8580&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg0 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8581&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg1 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8582&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg2 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8588&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg0 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8589&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg1 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x858A&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Quelle für Arg2 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8590&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg0 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8591&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg1 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8592&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg2 der RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8598&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg0 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8599&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg1 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x859A&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Teil der Quelle für Arg2 der Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_RGB_SCALE_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8573&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Scale Faktor für RGB Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ALPHA_SCALE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Scale Faktor für Alpha Berechnung angeben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_COMBINE_RGB_ARB''' oder '''GL_COMBINE_ALPHA_ARB''' ist, dann sind für ''param'' folgende Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_REPLACE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_MODULATE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 * Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ADD'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 + Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ADD_SIGNED_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8574&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 + Arg1 - 0.5&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_INTERPOLATE_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8575&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 * (Arg2) + Arg1 * (1-Arg2)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SUBTRACT_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x84E7&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Arg0 - Arg1&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_SOURCE0_RGB_ARB''', '''GL_SOURCE1_RGB_ARB''', '''GL_SOURCE2_RGB_ARB''', '''GL_SOURCE0_ALPHA_ARB''', '''GL_SOURCE1_ALPHA_ARB''', oder '''GL_SOURCE2_ALPHA_ARB''' ist, dann sind für ''param'' folgende Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_TEXTURE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Aktuelle Textur als Quelle verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_CONSTANT_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8576&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Mit [[glTexEnv]] für diese Textur gesetzte Farbe als Quelle verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_PRIMARY_COLOR_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8577&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Mit [[glColor]] oder vergleichbarem gesetzte Farbe als Quelle verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_PREVIOUS_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;0x8578&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Ergebnis der vorigen [[Texture Stage]] als Quelle verwenden oder gleich wie GL_PRIMARY_COLOR_ARB wenn es die erste [[Texture stage]] ist.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_OPERAND0_RGB_ARB''', '''GL_OPERAND1_RGB_ARB''' oder '''GL_OPERAND2_RGB_ARB''' ist, dann sind für ''param'' folgende Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''SRC_COLOR'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;RGB Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_COLOR'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;1-RGB Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Alpha Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;1-Alpha Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_OPERAND0_ALPHA_ARB''', '''GL_OPERAND1_ALPHA_ARB''' oder '''GL_OPERAND2_ALPHA_ARB''' ist, dann sind für ''param'' folgende Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Alpha Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ONE_MINUS_SRC_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;1-Alpha Teil der Quelle als Operand verwenden&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Für [[glTexEnv]]'''&lt;br /&gt;
wenn ''pname'' '''GL_RGB_SCALE_ARB''' oder '''GL_ALPHA_SCALE''' ist, dann sind für ''param'' folgende Werte gültig:&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''1.0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''2.0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''4.0'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== '''Neue States''' ===&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Name'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Abfrage mit'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''Initialwert'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_COMBINE_RGB_ARB '''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_MODULATE&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_COMBINE_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_MODULATE&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_TEXTURE&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_PREVIOUS_ARB&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_CONSTANT_ARB&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_TEXTURE&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_PREVIOUS_ARB&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_SOURCE2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_CONSTANT_ARB&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_COLOR&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_COLOR&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_RGB_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_ALPHA&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND0_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_ALPHA&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND1_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_ALPHA&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_OPERAND2_ALPHA_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnviv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GL_ALPHA&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_RGB_SCALE_ARB'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnvfv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;1.0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''GL_ALPHA_SCALE'''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;GetTexEnvfv&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;1.0&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Abhängigkeiten ==&lt;br /&gt;
[[GL_ARB_multitexture]]&lt;br /&gt;
&lt;br /&gt;
== Verwendungsbeispiel ==&lt;br /&gt;
Folgendender Code benutzt Multitexturing und texture_env_combine um über die erste Textur eine Zweite zu blenden. Die zweite Textur wird dabei mit einem Alphawert verrechnet. Das Ganze entspricht vom Ergebniss dem was man erreichen würde wenn man die Fläche mehrfach zeichnen (multi pass) würde und dabei als Blendfunktion GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA benutzen würde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  Color: array [0..3] of single;&lt;br /&gt;
begin&lt;br /&gt;
  glActiveTexture(GL_TEXTURE0);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);&lt;br /&gt;
  fTex.Bind;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Die erste Textur kann ganz normal an die TMU0 gebunden werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glActiveTexture(GL_TEXTURE1);&lt;br /&gt;
  fCube.Bind;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Die Zweite Textur wird auch normal gebunden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  Color[0] := 0;&lt;br /&gt;
  Color[1] := 0;&lt;br /&gt;
  Color[2] := 0;&lt;br /&gt;
  Color[3] := 0.125;&lt;br /&gt;
  glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, @Color);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Damit wird die Farbe gesetzt. Aus dieser Farbe wird im aktuellen Beispiel aber lediglich der Alphakanal benutzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
texture_env_combine aktivieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Die Kombinierungsart festlegen. Nähere informationen dazu wurden bereits oben beschrieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);&lt;br /&gt;
  glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Die einzelnen Operanden festlegen. Dieses richten sich nach der Kombinierungsart.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glBegin(GL_QUADS);&lt;br /&gt;
    glTexCoord2f(0, 1);&lt;br /&gt;
    glVertex3f(- 2, - 2, 0);&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
  glEnd;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Objekte zeichnen. In diesem Fall nur eine simple Fläche.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;  glActiveTexture(GL_TEXTURE1);&lt;br /&gt;
  fCube.Unbind;&lt;br /&gt;
&lt;br /&gt;
  glActiveTexture(GL_TEXTURE0);&lt;br /&gt;
  fTex.Unbind;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Die Texturen wieder aus dem TMUs entbinden.&lt;br /&gt;
&lt;br /&gt;
Mit diesem Code lässt sich auch auf Objekten eine leichte Spiegelung der Umgebung erzeugen. Dazu muss für die zweite Textur lediglich eine CubeMap oder SphereMap benutzt werden.&lt;br /&gt;
&lt;br /&gt;
== Ressourcen ==&lt;br /&gt;
[http://www.delphi3d.net/hardware/extsupport.php?extension=GL_ARB_texture_env_combine Hardware Unterstützung]&amp;lt;br&amp;gt;&lt;br /&gt;
[http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_combine.txt Original Extension-Spezifikation]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Dithering&amp;diff=20961</id>
		<title>Dithering</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Dithering&amp;diff=20961"/>
				<updated>2007-10-10T07:59:55Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Floyd-Steinberg Error Diffusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Unvollständig}}&lt;br /&gt;
{{Bildwunsch|Für die unterschiedlichen Verfahren ein Bild bitte.}}&lt;br /&gt;
== Übersicht ==&lt;br /&gt;
Dithering wird verwendet um mit wenigen Farben viele Farben zu simulieren. In den Printmedien wird Dithering häufig auch als ''Halftoning'' bezeichnet und verwendet. Hierbei werden schwarze und weisse Bildpunkte so angeordnet, dass man den Eindruck eines Graustufen-Bildes erhält.&lt;br /&gt;
Nachteil an der Sache ist, das meistens die Auflösung reduziert wird.&lt;br /&gt;
&lt;br /&gt;
== Dithering und OpenGL ==&lt;br /&gt;
Der verwendete Dithering-Algorithmus ist abhängig von der OpenGL-Implementierung. Allerdings kann ein guter Dithering-Algorithmus die Bildqualität auf Displays mit kleiner Farbzahl stark erhöhen. Dithering ist standardmässig eingeschaltet und kann mit [[glEnable]] bzw. [[glDisable]] und dem Parameter '''GL_DITHER''' kontrolliert werden.&lt;br /&gt;
Bei hoher Farbzahl ist Dithering nicht zwingend erforderlich und kann aus Perfomance-Gründen abgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
== Technischer Hintergrund ==&lt;br /&gt;
Aus Gründen der Übersichtlichkeit wird Dithering anhand von 256 Graustufen erläutert. Um Dithering auf Farbe anzuwenden, werden die vorgestellten Techniken auf jeden Farbkanal angewandt.&lt;br /&gt;
&lt;br /&gt;
=== Naive Ansätze ===&lt;br /&gt;
==== Down Scaling ====&lt;br /&gt;
[[Bild:Downscale.gif|right|framed|Wiki-Logo mit Downscaling]]&lt;br /&gt;
Im einfachsten Ansatz wird für jeden Pixel eine Entscheidung getroffen, welchen Wert er zugewiesen bekommt. Das heißt die Originalfarben werden gleichmäßig auf die reduzierte Palette aufgeteilt. Bei einer Reduktion auf Schwarz und Weiss werden z.B. Pixel mit einem Grauwert &amp;gt;= 128 auf Weisse Pixel und alle anderen Pixel auf Schwarz abgebildet.&lt;br /&gt;
&lt;br /&gt;
==== Random Decision ====&lt;br /&gt;
Eine deutliche Verbesserung erzielt man wenn die Entscheidung nicht über den Wert des Pixels getroffen wird, sondern dieser Wert als Wahrscheinlichkeit betrachtet wird ob ein Pixel gesetzt wird oder nicht. So wird ein Pixel mit einem Wert von 152 mit der Wahrscheinlichkeit 152/256 durch einen weissen Pixel ersetzt.&lt;br /&gt;
Die harten Kanten zwischen Weiss und Schwarz werden durch diese Weise zwar ersetzt, aber es ist ein ziemlich guter Zufallszahlen-Generator erforderlich um akzeptable Ergebnisse zu erhalten.&lt;br /&gt;
&lt;br /&gt;
==== Filling Patterns ====&lt;br /&gt;
Filling Patterns sind reguläre Muster, die dazu verwendet werden eine gewisse Anzahl an Graustufen abzubilden. Mit einem nxn Muster ist es möglich n*n+1 verschiedene Graustufen darzustellen. Als Beispiel die Muster für ein 2x2 (5 Graustufen) Muster.&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
 |+2x2 Muster = 5 Graustufen&lt;br /&gt;
 !width=&amp;quot;50px&amp;quot;|  0% &lt;br /&gt;
 !width=&amp;quot;50px&amp;quot;| 25%&lt;br /&gt;
 !width=&amp;quot;50px&amp;quot;| 50% &lt;br /&gt;
 !width=&amp;quot;50px&amp;quot;| 75% &lt;br /&gt;
 !width=&amp;quot;50px&amp;quot;| 100%&lt;br /&gt;
 |- align = &amp;quot;center&amp;quot;&lt;br /&gt;
 |00&amp;lt;br&amp;gt;00||10&amp;lt;br&amp;gt;00||10&amp;lt;br&amp;gt;01||11&amp;lt;br&amp;gt;01||11&amp;lt;br&amp;gt;11&lt;br /&gt;
|}&lt;br /&gt;
Hierbei sollte man versuchen die Pixel so irregulär wie möglich zu verteilen, da sonst sichtbare Artefakte (horizontale/vertikale) Linien in den Bilder entstehen. Das Muster wird auf einen gleichgrossen Bereich von Pixeln im Bild gelegt. Man berechnet den Mittelwert der Pixel unter dem Muster und entscheided dann, welches Muster anstelle der nxn Pixel verwendet wird.&lt;br /&gt;
&lt;br /&gt;
=== Dither Matrizen ===&lt;br /&gt;
Dither Matrizen sind eine Weiterentwicklung von Filling Patterns. Eine Dither-Matrix der Grösse nxn wird mit den Werten von [0..n*n-1] gefüllt und bewirkt eine Reduktion der Graustufen auf nxn+1.&lt;br /&gt;
Im Unterschied zu Filling Patterns werden hier allerdings die einzelnen Pixel stärker berücksichtigt. Je nach Art des Musters in dem die Werte in der Matrix verteilt werden spricht man von Clustered-Dot Dithering (Laserdrucker, Printmedien, etc.) oder Dispersed Dot Dithering.&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
 |+4x4 Dither-Matrizen&lt;br /&gt;
 !Dis&lt;br /&gt;
 !per&lt;br /&gt;
 !sed&lt;br /&gt;
 !Dot&lt;br /&gt;
 !---&lt;br /&gt;
 !Clu&lt;br /&gt;
 !ste&lt;br /&gt;
 !red&lt;br /&gt;
 !Dot&lt;br /&gt;
 |- align = &amp;quot;center&amp;quot;&lt;br /&gt;
 | 0|| 8|| 2||10||   ||13||10|| 6||14&lt;br /&gt;
 |- align = &amp;quot;center&amp;quot;&lt;br /&gt;
 |12|| 4||14|| 6||   || 5|| 0|| 3||11&lt;br /&gt;
 |- align = &amp;quot;center&amp;quot;&lt;br /&gt;
 | 3||11|| 1|| 9||   || 9|| 2|| 1|| 7&lt;br /&gt;
 |- align = &amp;quot;center&amp;quot;&lt;br /&gt;
 |15|| 7||13|| 5||   ||12|| 4|| 8||15&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Je nach Ausgabemedium werden unterschiedliche Verfahren angewendet.&lt;br /&gt;
Hat das Ausgabemedium eine höhere Auflösung als das Eingabebild, so werden die Dither-Matrizen auf jeden Pixel angewandt. Für jeden Pixel wird ein Wert berechnet, der im Wertebereich [0..n*n-1] liegt und in der Matrix werden alle Elemente &amp;lt; dieses Wertes angeschaltet. Eine weit verbreitete Methode zur Berechnung des Wertes ist der Modulo-Operator (C mod n*n - wobei C die aktuelle Pixelfarbe ist).&lt;br /&gt;
Bei niedrigerer Auflösung wird das gleiche Verfahren wie bei Filling Patterns angewandt, was die Auflösung allerdings drastisch reduziert.&lt;br /&gt;
Die Verteilung der Werte in der Matrix ist übrigens beliebig. Man sollte aber beachten das reguläre Muster zu sichtbaren Artefakten im Ausgabe-Bild führen.&lt;br /&gt;
&lt;br /&gt;
=== Floyd-Steinberg Error Diffusion ===&lt;br /&gt;
[[Bild:Dithering.gif|right|framed|Das Wiki-Logo mit Floyd-Steinberg Dithering vereinfacht.]]&lt;br /&gt;
Das Floyd-Steinberg Dithering arbeitet nach dem Error Diffusion Verfahren. Der Algorithmus sucht in der Farbpalette nach der bestmöglichen Farbe, die in den aktuellen Farbwert hineinpasst. Der Farbwert aus der Palette darf nicht größer sein als die eigentliche Farbe. Die Abweichung des Paletteneintrages zur ursprünglichen Farbe (auch Fehler genannt) wird nach einem festen Schema auf die umliegenden Pixel verteilt. Dadurch wird bewerkstelligt, dass das resultierende Bild, vom Pixeldurchschnitt her, so nah wie möglich an dem Original liegt.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;6&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| bgcolor=&amp;quot;#DDDDDD&amp;quot; | Pixel&lt;br /&gt;
|7/16&lt;br /&gt;
|-&lt;br /&gt;
|3/16&lt;br /&gt;
|5/16&lt;br /&gt;
|1/16&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Um die Entstehung von zu gleichmäßige Mustern zu verhindern wird abwechselnd je eine Zeile von Links und eine von Rechts verarbeitet.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
*OpenGL Superbible, 3rd. Edition, Wright &amp;amp; Lipchak, SAMS&lt;br /&gt;
*Computer Graphics - Principles and Practice, Second Edition in C, Foley &amp;amp; van Dam &amp;amp; Feiner &amp;amp; Hughes, Addison Wesley&lt;br /&gt;
*Skript zur Vorlesung Computer Graphics I, 1st Edit. 3rd Rev., Kobbelt &amp;amp; Sar-Dessai, Lehrstuhl für Informatik 8 - RWTH Aachen&lt;br /&gt;
*Périphériques de tracé, d'affichage et d'impression 2-D, Notes de cours, Hersch, Laboratoire de Systèmes Périphériques - EPFL&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_FontFaceStyleName&amp;diff=20824</id>
		<title>TTF FontFaceStyleName</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_FontFaceStyleName&amp;diff=20824"/>
				<updated>2007-09-14T18:04:38Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Die Seite wurde neu angelegt: = TTF_FontFaceStyleName =   == Name == '''TTF_FontFaceStyleName''' - Gibt den Namen des Stils der Schrift zurück.   == Delphi-Spezifikation ==  function '''TTF_FontFac...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_FontFaceStyleName =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''TTF_FontFaceStyleName''' - Gibt den Namen des Stils der Schrift zurück.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''TTF_FontFaceStyleName'''( ''font'' : PTTF_Font ) : pChar;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''font'' &lt;br /&gt;
| Eine geladene Schrift&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Gibt den Namen des Stils der Schrift zurück. Dabei handelt es sich unter Anderem um solche Angaben wie &amp;quot;regular&amp;quot;, &amp;quot;bold&amp;quot;, &amp;quot;italic&amp;quot; und viele mehr, da diese Texte von dem Schriftenersteller frei gewählt werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Ein '''nil''' an die Funktion erzeugt einen Segfault.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Rückgabewert ==&lt;br /&gt;
Der Rückgabewert ist ein Zeiger auf einen nullterminierten String. Sollte diese Information nicht verfügbar sein so ist der Rückgabewert '''nil'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_FontFaces]],  [[TTF_FontFaceIsFixedWidth]],  [[TTF_FontFaceFamilyName]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|FontFaceStyleName]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_FontFaceFamilyName&amp;diff=20823</id>
		<title>TTF FontFaceFamilyName</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_FontFaceFamilyName&amp;diff=20823"/>
				<updated>2007-09-14T17:57:03Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Die Seite wurde neu angelegt: = TTF_FontFaceFamilyName =   == Name == '''TTF_FontFaceFamilyName''' - Gibt den Namen der geladenen Schrift zurück.   == Delphi-Spezifikation ==  function '''TTF_FontF...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_FontFaceFamilyName =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''TTF_FontFaceFamilyName''' - Gibt den Namen der geladenen Schrift zurück.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''TTF_FontFaceFamilyName'''( ''font'' : PTTF_Font ) : pChar;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''font'' &lt;br /&gt;
| Eine geladene Schrift&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Gibt den Namen der geladenen Schrift zurück. Der Name ist normal das was man in allen Anwendungsprogrammen von einem Font zu sehen bekommt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Ein '''nil''' an die Funktion erzeugt einen Segfault.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Rückgabewert ==&lt;br /&gt;
Der Rückgabewert ist ein Zeiger auf einen nullterminierten String. Sollte diese Information nicht verfügbar sein so ist der Rückgabewert '''nil'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_FontFaces]],  [[TTF_FontFaceIsFixedWidth]],  [[TTF_FontFaceStyleName]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|FontFaceFamilyName]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_FontFaceIsFixedWidth&amp;diff=20822</id>
		<title>TTF FontFaceIsFixedWidth</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_FontFaceIsFixedWidth&amp;diff=20822"/>
				<updated>2007-09-14T17:40:10Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Die Seite wurde neu angelegt: = TTF_FontFaceIsFixedWidth =   == Name == '''TTF_FontFaceIsFixedWidth''' - Gibt zurück ob die übergebene Schrift eine nicht proportionale Schrift ist.   == Delphi-Spe...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_FontFaceIsFixedWidth =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''TTF_FontFaceIsFixedWidth''' - Gibt zurück ob die übergebene Schrift eine nicht proportionale Schrift ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''TTF_FontFaceIsFixedWidth'''( ''font'' : PTTF_Font ) : Integer;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''font'' &lt;br /&gt;
| Eine geladene Schrift&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Gibt zurück ob es sich um eine nicht proportionale Schrift handelt. Im Gegensatz zu proportionalen Schriften besitzen die Zeichen, bei nicht proportionalen, immer die gleiche Breite. Um die Breite eines Textes zu bestimmen genügt also die Breite eines einzelnen Zeichens. Typisches Einsatzgiet von nicht proportionalen Schriften sind Befehlskonsolen und Texteditore jeglicher Art. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Ein '''nil''' an die Funktion erzeugt einen Segfault.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Rückgabewert ==&lt;br /&gt;
Der Rückgabewert ist größer 0 wenn es sich um eine nicht proportionale Schrift handelt ansonsten 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_FontFaces]],  [[TTF_FontFaceFamilyName]],  [[TTF_FontFaceStyleName]],  [[TTF_GlyphMetrics]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|FontFaceIsFixedWidth]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_FontFaces&amp;diff=20821</id>
		<title>TTF FontFaces</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_FontFaces&amp;diff=20821"/>
				<updated>2007-09-14T17:32:44Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* TTF_FontFaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_FontFaces =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''TTF_FontFaces''' - Gibt die Anzahl der, in einer Schriftdatei enthalten, Schriften (Unterschriften) zurück.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''TTF_FontFaces'''( ''font'' : PTTF_Font ) : Longint;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''font'' &lt;br /&gt;
| Eine geladene Schrift&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
In manchen Schriftdateien gibt es die Möglichkeit gleich mehrere Schriften abzulegen. TTF_FontFaces gibt die Anzahl der Unterschriften zurück. Diese Information ist allerdings recht nutzlos, da SDL_ttf nirgendswo die Ansteuerung von Unterschriften ermöglicht. Da aber nahezu alle Schriften so etwas nicht unterstützen ist das auch nicht weiter tragisch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Ein '''nil''' an die Funktion erzeugt einen Segfault.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Rückgabewert ==&lt;br /&gt;
Die Anzahl der enthalten Unterschriften.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_FontFaceIsFixedWidth]],  [[TTF_FontFaceFamilyName]],  [[TTF_FontFaceStyleName]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|FontFaces]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_FontFaces&amp;diff=20820</id>
		<title>TTF FontFaces</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_FontFaces&amp;diff=20820"/>
				<updated>2007-09-14T17:26:14Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Die Seite wurde neu angelegt: = TTF_FontFaces =   == Name == '''TTF_FontFaces''' - Gibt die Anzahl der, in einer Fontdatei enthalten, Fonts (Subfonts) zurück.   == Delphi-Spezifikation ==  function...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_FontFaces =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''TTF_FontFaces''' - Gibt die Anzahl der, in einer Fontdatei enthalten, Fonts (Subfonts) zurück.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''TTF_FontFaces'''( ''font'' : PTTF_Font ) : Longint;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''font'' &lt;br /&gt;
| Eine geladene Schrift&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
In manchen Fontsdateien gibt es die Möglichkeit gleich mehrere Fonts abzulegen. TTF_FontFaces gibt die Anzahl der Fonts (Subfonts) zurück. Diese Information ist allerdings recht nutzlos, da SDL_ttf nirgendswo die Ansteuerung von Subfonts ermöglicht. Da aber nahezu alle Fonts so etwas sowieso nicht unterstützen ist das auch nicht weiter tragisch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Ein '''nil''' an die Funktion erzeugt einen Segfault.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Rückgabewert ==&lt;br /&gt;
Die Anzahl der enthalten Subfonts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_FontFaceIsFixedWidth]],  [[TTF_FontFaceFamilyName]],  [[TTF_FontFaceStyleName]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|FontFaces]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TTF_Rendermode&amp;diff=20806</id>
		<title>TTF Rendermode</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TTF_Rendermode&amp;diff=20806"/>
				<updated>2007-09-14T11:09:18Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Anwendung in OpenGL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TTF_Rendermode =&lt;br /&gt;
&lt;br /&gt;
[[SDL_TTF]] kennt drei verschiedene Rendermodi:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Solid ==&lt;br /&gt;
'''Quick and Dirty'''&lt;br /&gt;
&lt;br /&gt;
Erstellt eine 8-Bit palettierte [[SDL_Surface|Surface]] und rendert den gegebenen Text in schneller Qualität mit der gegebenen Schrift und Farbe. Der Pixelwert 0 ist der Colorkey, der den transparenten Hintergrund vorgibt, wenn es kopiert wird. Pixel- und Colormapwert 1 wird für die Vordergrundfarbe des Textes gesetzt. Dies erlaubt die Textfarbe zu ändern ohne den Text neuzurendern. Der Palettenindex 0 wird natürlich nicht gezeichnet, wenn es auf eine andere Surface kopiert wird, seitdem es ein Colorkey und somit die Transparenz ist, da die aktuelle Farbe 255 minus jeden der RGB Komponenten der Vordergrundfarbe ist.&lt;br /&gt;
&lt;br /&gt;
Dies ist der schnellste Rendermodus von allen. Das Resultat hat keine Box um den Text, dafür ist der Text nicht glatt. Dieser Modus ist für FPS und andere schnell aktualisierende Textanzeigen geeignet.&lt;br /&gt;
&lt;br /&gt;
[[Bild:TTF solid.png|framed|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Shaded ==&lt;br /&gt;
'''Slow and Nice, but with a Solid Box'''&lt;br /&gt;
&lt;br /&gt;
Erstellt eine [[SDL_Surface|Surface]] mit einer 8-Bit Farbpalette und rendert den gegebenen Text in hoher Qualität mit der gegebenen Schrift und Farbe. Der 0 Pixelwert ist der Hintergrund, während die anderen Pixel variirende Farben zwischen der Vordergrundfarbe und Hintergrundfarbe sind. Dies resultiert in eine Box mit der Farbe des Hintergrundes um den Text in der Vordergrundfarbe. Der Text ist antialiased. Das Rendern ist langsamer als Solid, aber in ungefähr der selben Zeit wie Blended. Die resultierende Surface sollte sich so schnell wie eine 'Solid-Surface' kopieren lassen. Geeignet für netten Text wenn man zeitgleich mit der Box leben kann.&lt;br /&gt;
&lt;br /&gt;
[[Bild:TTF blended.png|framed|center]]&lt;br /&gt;
&lt;br /&gt;
== Blended ==&lt;br /&gt;
'''Slow Slow Slow, but Ultra Nice over another image'''&lt;br /&gt;
&lt;br /&gt;
Erstellt eine 32-Bit ARGB [[SDL_Surface|Surface]] und rendert den gegebenen Text in hoher Qualität unter Benutzung von [[Blenden|Alpha Blending]]. Dies resultiert in eine Surface mit Alpha Transparenz, sodass man keine solide farbige Box um den Text hat. Der Text ist antialiased. Das Render ist langsamer als Solid, aber in der selben Zeit wie im Shaded Modus. Die resultierende Surface lässt sich langsamer kopieren als bei Solid oder Shaded. Zu benutzen, wenn man hohe Qualität haben will und der Text sich nicht zu oft ändert.&lt;br /&gt;
&lt;br /&gt;
[[Bild:TTF blended.png|framed|center]]&lt;br /&gt;
&lt;br /&gt;
== Anwendung in OpenGL ==&lt;br /&gt;
Der Modus &amp;quot;Blended&amp;quot; liefert direkt die passende Textur, um eine schöne Schrift zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
var surface : PSDL_Surface;&lt;br /&gt;
    tex     : GLUint;&lt;br /&gt;
begin&lt;br /&gt;
  surface :=TTF_RenderText_Blended(font,'Fischer''s Frase fischt frische Forellen', color);&lt;br /&gt;
  //lädt die Daten aus der Surface in den Speicher:&lt;br /&gt;
  tex     :=SDL_GL_LoadTexture(surface);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Zeichnen per Alphatest ===&lt;br /&gt;
Doch wie zeichnet man die Schrift den jetzt?&lt;br /&gt;
Ich habe es bisher immer wie bei Sascha's [[Tutorial_Bomberman2#Texturenfonts|BombermanFontUnit]] gemacht:&lt;br /&gt;
&amp;lt;pascal&amp;gt;  &lt;br /&gt;
  glEnable(GL_ALPHA_TEST);&lt;br /&gt;
  glAlphaFunc(GL_GREATER, 0.1);&lt;br /&gt;
  //Zeichnen der Textur&lt;br /&gt;
  glDisable(GL_ALPHA_TEST);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Resultat sieht dann so aus:&lt;br /&gt;
[[Bild:TTF Alpha.png|thumb|center|Anklicken für grosse Darstellung]]&lt;br /&gt;
&lt;br /&gt;
Im Prinzip also wie [[TTF_RenderText_Solid]], was auch klar ist, wenn man sich anschaut was der Alphatest genau macht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Zeichnen per Blenden ===&lt;br /&gt;
Eine Alternative ist das Blenden:&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);&lt;br /&gt;
  glEnable(GL_BLEND);&lt;br /&gt;
  //Zeichnen der Textur&lt;br /&gt;
  glDisable(GL_BLEND);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ergebnis:&lt;br /&gt;
[[Bild:TTF Blending.png|thumb|center|Anklicken für grosse Darstellung]]&lt;br /&gt;
Die Schrift wird an den Kanten leicht mit dem Hintergrund vermischt. Dadurch wirkt sie wesentlich ruhiger und lässt sich besser lesen.&lt;br /&gt;
&lt;br /&gt;
=== Hinweis ===&lt;br /&gt;
Eine Demo-Anwendung zu SDL_TTF kann man im [[DGLSDK]]-[[SVN]] finden.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[TTF_RenderText_Solid]], [[TTF_RenderText_Shaded]], [[TTF_RenderText_Blended]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDLTTF|Rendermode]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=dglOpenGL.pas&amp;diff=20300</id>
		<title>dglOpenGL.pas</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=dglOpenGL.pas&amp;diff=20300"/>
				<updated>2007-04-09T13:36:19Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hinweis| '''Im Lieferumfang von Delphi ist bereits ein OpenGL Header enthalten. Dieser Header ist allerdings ''veraltet und fehlerhaft''. Unter anderem wurden Befehlsbezeichner nicht korrekt übernommen. ''Es wird daher dringend davon abgeraten diesen Header zu benutzen.'''''}}&lt;br /&gt;
&lt;br /&gt;
=Der DelphiGL-Header=&lt;br /&gt;
Für alle die OpenGL unter Delphi nutzen möchten hat die [http://www.delphigl.com DelphiGL Community] einen Header zur Verfügung gestellt.&lt;br /&gt;
&lt;br /&gt;
Der Header enthält alle aktuellen OpenGL-Funktionen sowie alle aktuellen GLU-Funktionen.&lt;br /&gt;
&lt;br /&gt;
Des weiteren sind alle ARB-, EXT-, NV- und ATI- Extensions enthalten sowie einige weitere Extensions von anderen Herstellern (Apple, HP, SGI...)&lt;br /&gt;
&lt;br /&gt;
Als besonderer Service bei den Extensions enthält der Header eine Booleanvariablen für jede Extension die automatisch bei Initialisieren gesetzt wird. Diese Booleanvariable (die den gleichen Namen wie der Abfragestring hat) gibt dann an, ob die Extension verfügbar ist oder nicht. (Man erspart sich damit die Stringauswertung bei [[glGetString]].)&lt;br /&gt;
&lt;br /&gt;
Der Header wird von der DGL-Community gepflegt und auf dem neuesten Stand gehalten. Dadurch wird es den Nutzern des Headers sehr leicht gemacht bei neuen OpenGL Versionen einfach den neuen Header in ihre Programme einzubinden (Man muss nur den alten durch den neuen Header ersetzen). Weiterhin ist es auch möglich den Header unter anderen Pascalplattformen wie z.B. Freepascal zu benutzen.&lt;br /&gt;
&lt;br /&gt;
==Hinweis==&lt;br /&gt;
Seit der Headerversion 2.1 unterstützt der reguläre Header kein .NET mehr. Mit dem Entfernen der .NET Unterstützung wurde auch eine Technik entfernt die es dem Header möglich gemacht hat benötigte Methoden dynamisch nachzuladen. Dies Funktioniert jetzt nicht mehr. Ihr müsste also nachdem ihr euren Kontex erstellt habe ihn entweder über ''ActivateRenderingContext'' aktivieren oder aber es muss ''ReadExtensions'' und ''ReadImplementationProperties'' von Hand aufgerufen werden. Solltet ihr Zugriffsverletzungen an Adresse 0x00000000 bekommen wo vorher keine waren. Überprüft das.&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;
'''Hier könnt ihr den aktuellen [http://files.delphigl.com/download/dglOpenGL.zip dglOpenGL.pas Header downloaden].'''&lt;br /&gt;
&lt;br /&gt;
'''Hier könnt ihr den aktuellen [http://files.delphigl.com/download/dglOpenGL_net.zip dglOpenGL.pas Header mit .NET Unterstützung downloaden].'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''[[Benutzer:Mars|Mars]] hat im DGL-Forum ein '''abgewandelte Form der dglOpenGL.pas''' gepostet, welche auch mit '''Delphi 3''' funktioniert:''&amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.delphigl.com/forum/viewtopic.php?p=26697#25642 dglOpenGL.pas für Delphi 3] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''Weiterhin existiert eine inoffizielle Version des Headers für C++.''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glCompileShader&amp;diff=20181</id>
		<title>glCompileShader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glCompileShader&amp;diff=20181"/>
				<updated>2007-02-12T19:18:31Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Delphi-Spezifikation */ prcedur statt function&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glCompileShader (glCompileShaderARB)=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glCompileShader''' - Kompiliert ein Shaderobjekt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 procedure '''glCompileShader'''(''shaderObj'' : GLHandle);&lt;br /&gt;
 procedure '''glCompileShaderARB'''(''shaderObj'' : GLHandleARB);&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''shaderObj''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Handle des zu kompilierenden Shaderobjektes.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
'''glCompileShader''' kompiliert den Quellcode der im Shaderobjekt abgelegt ist, wobei der Status der Kompilation als Teil des Objektstatus des Shaderobjektes gespeichert wird. Dieser Wert ist True, wenn der Shader ohne Fehler kompiliert wurde und bereit zur Nutzung ist, und ansonsten False. Er kann mittels [[glGetObjectParameterARB]] und dem Shader sowie ''GL_OBJECT_COMPILE_STATUS'' als Argument abgefragt werden.&lt;br /&gt;
&lt;br /&gt;
Die Kompilierung des Shaders kann aus vielerlei Gründen scheitern, die genauer in den Spezifikationen der OpenGL-Shadersprache aufgelistet sind. Ob die Kompilierung erfolgreich war, kann aus dem Informationslog des Shaderobjektes via [[glGetInfoLogARB]] ermittelt werden.&lt;br /&gt;
&lt;br /&gt;
Seit der OpenGL Version 2.0 ist '''glCompileShader''' im Kern enthalten. Die alte ARB Bezeichnung war '''glCompileShaderARB'''.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn der Shader kein gültiges OpenGL-Handle ist.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn der Shader nicht vom Typ ''GL_SHADER_OBJECT'' ist.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn '''glCompileShaderARB''' zwischen einem [[glBegin]] und dem passenden [[glEnd]] aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGetInfoLog]] mit dem Argument ''shaderObj''.&lt;br /&gt;
&lt;br /&gt;
[[glGetObjectParameterARB]] mit den Argumenten ''shaderObj'' und ''GL_OBJECT_COMPILE_STATUS''. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glCreateShaderObjectARB]], [[glLinkProgram]], [[glShaderSource]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''Hintergrundwissen :''' [[Shader]]&amp;lt;br&amp;gt;&lt;br /&gt;
[http://developer.3dlabs.com/openGL2/slapi/CompileShaderARB.htm Englische Originalversion]  (Copyright 3DLabs Inc.)&lt;br /&gt;
[[Kategorie:GL|CompileShader]]&lt;br /&gt;
[[Kategorie:SHADER_OBJECTS|CompileShader]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Farbraum&amp;diff=19530</id>
		<title>Farbraum</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Farbraum&amp;diff=19530"/>
				<updated>2006-09-01T07:54:22Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Hier ist als Linktext immer etwas ungenau&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Übersicht ==&lt;br /&gt;
Farbräume dienen der Darstellung von Farben. Üblicherweise werden alle an Monitoren darstellbaren Farben durch 3 Grundtöne codiert. Durch verschieden starke Abstufungen dieser 3 Grundtöne entsteht der Eindruck von verschiedenen Farben. &lt;br /&gt;
&lt;br /&gt;
== Grundlegende Bildschirmkalibrierung ==&lt;br /&gt;
Um die dargestellten Farben an Computermonitoren optimal anzuzeigen, muss der Monitor zuerst kalibriert werden. Für unsere Zwecke soll eine einfache Kalibrierung ausreichen: In professionellem Umfeld kommt es nicht nur auf optimale Farbdarstellung an, sondern auch auf Farbechtheit. Um dies zu erreichen ist nicht ganz billiges Equipment notwendig. Wir wollen uns deshalb auf ein paar Hausmittel beschränken. Tatsächlich sind die meisten Computermonitore derart schlecht eingestellt, daß man bei weitem nicht von guter Farbdarstellung reden kann. Bevor wir also weitermachen, wollen wir diesen Umstand ändern. Zuerst muss der Monitor jedoch warm sein - also mindestens eine Stunde in Betrieb sein, bevor er eingestellt wird. &lt;br /&gt;
&lt;br /&gt;
=== Schwarzpunkt ===&lt;br /&gt;
Macht euer Zimmel dunkel. Alle Beleuchtung muss abgestellt werden. Eventuelle Rolläden werden bitte geschlossen. Stellen wir die Helligkeit des Monitors auf das Minimum und betrachten das untere Bild (wenn du nach dem dunkelstellen nichts mehr sehen kannst solltest du den folgenden Teil der Anleitung vorher durchlesen):&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Schwarzpunkt.png|center]]&lt;br /&gt;
&lt;br /&gt;
Stelle nun die Helligkeit soweit nach oben, bis das schwarze Bild gerade beginnt heller zu erscheinen. Ist dieser Punkt erreicht, dann stelle die Helligkeit wieder ein kleines Stück zurück, so daß es wieder komplett schwarz ist. Wenn das Bild partout nicht hell werden möchte, dann stelle die Helligkeit auf ein Maß, so daß der Mointor nicht zu hell leuchtet ( ein zu heller Monitor ist sehr unangenehm für die Augen. Wenn ihr beim längeren arbeiten Augenschmerzen oder Tränen in den Augen bekommt, dann stellt die Helligkeit unbedingt weiter zurück. Soviel ist der optimale Schwarzpunkt nicht wert. ). '''Achtung TFT Benutzer:''' Der Helligkeitsverlauf auf TFT Monitoren ist nicht konstant. Ich empfehle deshalb das Bild etwa mittig zu plazieren.&lt;br /&gt;
&lt;br /&gt;
=== Kontrast und Gamma === &lt;br /&gt;
[[Bild:Farbräume_Kontrast.png|center]]&lt;br /&gt;
&lt;br /&gt;
Betrachtet bei den obigen Farbverläufen den von Schwarz nach Weiß. Alle 24 Felder sind gleich groß. Der erste Übergang von Schwarz nach etwas Helligkeit sollte in etwa so stark ausfallen, wie der von Weiß auf die erste Abstufung. Regelt die Kontrasteinstellung eures Monitores solange bis beide Übergänge tatsächlich sichtbar sind und in etwa gleich stark ausfallen. Die anderen Felder sollten sich dann bereits halbwegs angepasst haben: Der Verlauf erscheint linear. Wenns noch nicht ganz passt, könnt ihr am Monitor ( wenn das der Monitor nicht bietet, benutzt die Einstellungsmöglichkeiten eures Grafikkartentreibers ) den Gammawert noch ein wenig korrigieren. &lt;br /&gt;
&lt;br /&gt;
Falls ihr gerne noch etwas mehr Zeit investieren wollt, dann schaut doch mal bei [http://tom.via.de/Fotoseiten/Kalibrierung/kalibrierung.asp Tom Kurpjuweit] oder im [http://de.wikipedia.org/wiki/Gammakorrektur#Gamma-Testgrafik Wikipedia] vorbei. Auf diesen und auf vielen anderen Seiten im Netz wird beschrieben, wie man seinen Monitor einstellen kann - meine Anleitung gehört doch eher zu den primitiven. Falls das Bild des Monitors jetzt eher grau und milchig erscheint, seid ihr wahrscheinlich dem Problem erlegen, daß unsere Augen logarithmische Farbveränderungen bevorzugen und lineare Verläufe eher ungewohnt sind - dann ist es Zeit, sich eine etwas genauere Beschreibung zum Thema Bildschirm-justierung/kalibrierung durchzulesen.&lt;br /&gt;
&lt;br /&gt;
== Physikalische und biologische Grundlagen ==&lt;br /&gt;
Physikalisch besteht Licht aus Wellen. Diese haben verschiedene Wellenlaengen und je nach Zusammensetzung entsteht der eine oder der andere Farbeindruck.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Farbspektrum.png|center]] &lt;br /&gt;
&lt;br /&gt;
Das sichtbare Licht hat Wellenlängen zwichen 400nm (Violett) bis 750 nm (Rot). Bei kürzeren Wellenlängen unter 400nm kommen dann Ultra Violette, Röntgen und schließlich Gamma Strahlen. Auf der anderen Seite über 750 nm folgen Infrarot, Mikrowellen, Funkempfang (LW, MW, UKW, ...), usw. Auf dem Monitor lassen sich nicht alle Reinfarben darstellen, seht das obige Bild also eher als Eindruck statt als &amp;quot;so siehts also aus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Da unser Auge nur 3 Grundfarben unterscheiden kann (manche Menschen können sogar 4 Farben unterscheiden, wieder andere dagegen nur 2.), kann man verschiedene Farbeindrücke nicht nur durch verschiedene Wellenlängen erzeugen,  sondern auch durch das Mischen und Verlagern der Intensitäten einer Reihe von Grundfarben. So wird am Monitor  bekanntlich (additiv) mit Rot, Grün und Blau, auf Printmedien üblicherweise (subtraktiv) mit Cyan, Gelb, Magenta und Schwarz gemischt. Man kann so zwar nicht jede sichtbare Farbe mischen, aber doch so viele, daß ein guter Farbeindruck entsteht.&lt;br /&gt;
&lt;br /&gt;
== Verschiedene Farbräume ==&lt;br /&gt;
=== RGB ===&lt;br /&gt;
Der Rot, Grün, Blau Farbraum ist der Standardfarbraum für Computer und viele andere Bildschirmgeräte. Damit Farben aus anderen Farbräumen auf einem solchen Gerät dargestellt werden können, müssen sie immer zuerst auf diesen Farbraum umgerechnet werden. Er ist neben CMY einer der am wenigsten anschaulichen Farbräume. Farben lassen sich darin nur sehr schlecht identifizieren, sinnvolle Farbmanipulationen sind kaum möglich. Der Vorteil ist jedoch, daß die 3 Grundfarben etwa denen entsprechen, die auch auf unserer Netzhaut am besten erkannt werden - die Folge: höchst brilliante Farben, die einen großen Teil aller sichtbaren Farben abdecken. Den Farbraum kann man sich als dreidimensionalen Würfel am Nullpunkt vorstellen:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_RGB.png|center]] &lt;br /&gt;
&lt;br /&gt;
Ausgehend vom Schwarz kann man nach rechts (Rot), nach oben (Grün) oder nach vorne (Blau) laufen und erhält immer hellere Farben. Schließlich gelangt man zum Weiß. Dazu gibt es auch eine weitere Veranschaulichung:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_RGB_additiv.png|center]] &lt;br /&gt;
&lt;br /&gt;
=== CMY ===&lt;br /&gt;
Der Cyan, Magenta, Gelb Farbraum ist dem RGB Farbraum sehr ähnlich. Allerdings ist er für Printmedien konzipiert. Ist keine Farbe aufgetragen, so erhält man den Hintergrund - meist ein weißes Blatt Papier. Je mehr man von einer Farbe aufträgt, desto weniger scheinen die anderen Farben durch - trägt man also alle Farben auf, bleibt vom ursprünglichen Weiß nichts über und man erhält Schwarz. Da jedoch der Hintergrund im Allgemeinen nicht leuchtet, können Farben nie derart hell erscheinen, wie im RGB Farbraum - man möge dies bei Druck-Anwendungen beachten:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_CYM.png|center]] &lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_CYM_subtraktiv.png|center]]&lt;br /&gt;
&lt;br /&gt;
Zum Umrechnen von RGB in CMY ist nicht viel nötig:&lt;br /&gt;
 R = 1-C&lt;br /&gt;
 G = 1-M&lt;br /&gt;
 B = 1-Y&lt;br /&gt;
Und umgekehrt:&lt;br /&gt;
 C = 1 - R&lt;br /&gt;
 M = 1 - G&lt;br /&gt;
 Y = 1 - B&lt;br /&gt;
&lt;br /&gt;
=== CMYK ===&lt;br /&gt;
Der CMYK Farbraum entspricht im wesentlichen dem CMY Farbraum, mit dem Unterschied, daß zusätzlich Schwarz zum Beimischen zur Verfügung steht. Dies kann beim Drucken von sehr dunklen Tönen hilfreich sein und spart ausserdem die teure Farbe. In manchen Fällen ist es sogar unumgänglich mit Schwarz zu drucken, wenn sich durch die anderen Druckfarben kein richtiges Schwarz erzeugen lässt (was häufig der Fall ist, u.a. auch bei den meisten Tintendruckern). &lt;br /&gt;
&lt;br /&gt;
Umrechnen CMYK nach CMY:&lt;br /&gt;
 CMY.C = C * ( 1 - K ) + K&lt;br /&gt;
 CMY.M = M * ( 1 - K ) + K&lt;br /&gt;
 CMY.Y = Y * ( 1 - K ) + K&lt;br /&gt;
&lt;br /&gt;
Umrechnen CMY nach CMYK&lt;br /&gt;
 CMYK.K = min(C,M,Y);&lt;br /&gt;
 if ( CMYK.K == 1 ) { &lt;br /&gt;
   CMYK.C = 0;   &lt;br /&gt;
   CMYK.M = 0;&lt;br /&gt;
   CMYK.Y = 0;&lt;br /&gt;
 } else {&lt;br /&gt;
   CMYK.C = (C-CMYK.K)/(1-CMYK.K);   &lt;br /&gt;
   CMYK.M = (M-CMYK.K)/(1-CMYK.K);   &lt;br /&gt;
   CMYK.Y = (Y-CMYK.K)/(1-CMYK.K);   &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== HSV ===&lt;br /&gt;
Der Hue, Saturation, Value (Farbton, Sättigung, Helligkeit) ist ein Farbraum, der sehr häufig im Einsatz ist. Da der Farbton als solches an einem Kanal zu identifizieren ist, werden viele Bildoperationen, die mit Farbe zu tun haben, in eben diesem Farbraum berechnet. Eine bildliche Vorstellung dieses Farbraums ist sehr viel einfacher, als die des RGB Farbraums. Wie also kann man sich ihn vorzustellen?&lt;br /&gt;
&lt;br /&gt;
Eine gute Möglichket ist als Zylinder. Die Unterseite ist schwarz. Bewegt man sich von der Mitte der Unterseite auf die gegenüberliegende Seite zu, wird es heller. Inmitten der hellen Seite ist Weiß. Geht man von dort nach aussen, erhöht sich die Farbsättigung. Geht man dann auf dem Kreis spazieren, bleibt Helligkeit und Sättigung konstant, während sich die Farbe ändert. Dieses Prinzip wird bei vielen Farbauswahldialogen angewendet (Im Beispiel: Paint.NET) :&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_HSV_auswahl1.png|center]] &lt;br /&gt;
&lt;br /&gt;
Der Kreis stellt die farbige Oberseite des Zylinders dar. Von der Mitte nach Aussen also die Sättigung, den Umfang entlang die Farbe. Der Balken beschreibt die Helligkeit. Sehr beliebt ist auch die aufgefaltete Variante (MS-Windows Standard Farbauswahl Dialog):&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_HSV_auswahl2.png|center]]&lt;br /&gt;
&lt;br /&gt;
Im quadratischen Feld ist von Links nach Rechts die Farbe, von Unten nach Oben die Sättigung aufgetragen. Der Balken gibt wieder die Helligkeit an. &lt;br /&gt;
&lt;br /&gt;
Es existieren noch viele verschiedene Varianten, die alle mehr oder weniger identisch funktionieren. Wir wollen es bei diesen zwei Beispielen belassen.&lt;br /&gt;
&lt;br /&gt;
Die Farbreihenfolge wird gewöhnlich definiert als Rot, Magenta, Blau, Cyan, Grün, Gelb, Rot. Zwischen den Vollfarben wird linear interpoliert, was zu folgenden Umrechnungen führt:&lt;br /&gt;
&amp;lt;cpp&amp;gt;&lt;br /&gt;
        // Based on C Code in &amp;quot;Computer Graphics -- Principles and Practice,&amp;quot;&lt;br /&gt;
        // Foley et al, 1996, p. 593.&lt;br /&gt;
        public static RGB HSVToRGB(double h, double s, double v)&lt;br /&gt;
        {&lt;br /&gt;
            double f, hTemp, p,q,t;&lt;br /&gt;
            int i;&lt;br /&gt;
            RGB Result = new RGB();&lt;br /&gt;
            if (s == 0) {&lt;br /&gt;
                //Achromatic&lt;br /&gt;
                Result.R = v;&lt;br /&gt;
                Result.G = v;&lt;br /&gt;
                Result.B = v;&lt;br /&gt;
                return Result;&lt;br /&gt;
            }&lt;br /&gt;
            if (h &amp;lt; 0)&lt;br /&gt;
                h = Math.PI * 2 - h;&lt;br /&gt;
       &lt;br /&gt;
            if (h &amp;gt; 2 * Math.PI)&lt;br /&gt;
                h = h - Math.Truncate(1.0 / (Math.PI * 2) *h)* (Math.PI * 2);&lt;br /&gt;
         &lt;br /&gt;
            hTemp = h / (2*Math.PI / 6);&lt;br /&gt;
            i = (int) Math.Truncate(hTemp);  // largest integer &amp;lt;= h&lt;br /&gt;
            f = hTemp - i;                   // fractional part of h&lt;br /&gt;
     &lt;br /&gt;
            p = v * (1.0 - s);&lt;br /&gt;
            q = v * (1.0 - (s * f));&lt;br /&gt;
            t = v * (1.0 - (s * (1.0 - f)));&lt;br /&gt;
              &lt;br /&gt;
            switch (i) {&lt;br /&gt;
                case 0: { Result.R = v; Result.G = t; Result.B = p; break; }&lt;br /&gt;
                case 1: { Result.R = q; Result.G = v; Result.B = p; break; }&lt;br /&gt;
                case 2: { Result.R = p; Result.G = v; Result.B = t; break; }&lt;br /&gt;
                case 3: { Result.R = p; Result.G = q; Result.B = v; break; }&lt;br /&gt;
                case 4: { Result.R = t; Result.G = p; Result.B = v; break; }&lt;br /&gt;
                case 5: { Result.R = v; Result.G = p; Result.B = q; break; }&lt;br /&gt;
            }&lt;br /&gt;
            return Result;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // Based on C Code in &amp;quot;Computer Graphics -- Principles and Practice,&amp;quot;&lt;br /&gt;
        // Foley et al, 1996, p. 594.&lt;br /&gt;
        public static HSV RGBToHSV(double r, double g, double b)&lt;br /&gt;
        {&lt;br /&gt;
            HSV result = new HSV();&lt;br /&gt;
            double delta, min;&lt;br /&gt;
    &lt;br /&gt;
            min = Math.Min(r, Math.Min(g, b));&lt;br /&gt;
            result.v = Math.Max(r, Math.Max(g, b));&lt;br /&gt;
            delta = result.v - min;&lt;br /&gt;
        &lt;br /&gt;
            // Calculate saturation: saturation is 0 if r, g and b are all 0&lt;br /&gt;
            if (result.v == 0.0)&lt;br /&gt;
                result.s = 0;&lt;br /&gt;
            else&lt;br /&gt;
                result.s = delta / result.v;&lt;br /&gt;
   &lt;br /&gt;
            if (result.s == 0)&lt;br /&gt;
                result.h = 0; //Achromatic&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                if (r == result.v)&lt;br /&gt;
                {   //winkel zw. gelb/magenta&lt;br /&gt;
                    result.h = (g - b) / delta * (2 * Math.PI / 6.0);&lt;br /&gt;
                }&lt;br /&gt;
                else if (g == result.v)&lt;br /&gt;
                {    //zwischen cyan und gelb&lt;br /&gt;
                    result.h = (2 + (b - r) / delta) * (2 * Math.PI / 6.0);&lt;br /&gt;
                }&lt;br /&gt;
                else if (b == result.v)&lt;br /&gt;
                {// ...&lt;br /&gt;
                    result.h = (4 + (r - g) / delta) * (2 * Math.PI / 6.0);&lt;br /&gt;
                }&lt;br /&gt;
                if (result.h &amp;lt; 0)&lt;br /&gt;
                    result.h = result.h + 2 * Math.PI;&lt;br /&gt;
            }&lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HSL ===&lt;br /&gt;
Der Hue Saturation Lightness Farbraum ist dem HSV Farbraum sehr ähnlich. Die Definition des Farbtons (Hue) ist identisch, lässt sich also auf die gleiche Weise berechnen. Die anderen Werte berechnen sich aus den RGB Werten wie folgt:&lt;br /&gt;
 MAX = max (R,G,B);&lt;br /&gt;
 MIN = min (R,G,B);&lt;br /&gt;
 &lt;br /&gt;
 L = (1.0/2.0) * (MAX + MIN);&lt;br /&gt;
 if (MIN == MAX) &lt;br /&gt;
 {&lt;br /&gt;
   S = 0&lt;br /&gt;
 } else if (L &amp;lt;= 1.0/2.0) {&lt;br /&gt;
   S = (MAX - MIN) / (2.0*L) &lt;br /&gt;
 } else {&lt;br /&gt;
   // entspr. Fall: L &amp;gt; 1.0/2.0&lt;br /&gt;
   S = (MAX - MIN) / (2.0-2.0*L)  &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Man stellt sich den HSV Farbraum gerne als Doppelkonus vor. Die obere Spitze ist weiß, die untere schwarz. Am Rand des Bauches befinden sich die Vollfarben, die zur Mitte hin an Sättigung verlieren (Bild: Wikipedia [EN]):&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Color_Cones.png|center]]&lt;br /&gt;
&lt;br /&gt;
=== LAB ===&lt;br /&gt;
Der LAB Farbraum ist einer an das menschliche Sehen angepasster Farbraum. Er umfasst alle vom Auge unterscheidbaren Farben und ein bischen mehr. Er dient dazu, Farbechtheit zu garantieren, was wichtig ist, wenn man z.B. am Bildschirm Bilder bearbeitet und diese am Ende drucken oder auf Fotopapier auslasern lassen möchte, so daß die Vorlage am Monitor dem entspricht, was auf dem Papier landen wird. Er dient dabei nur als Umrechnungsfarbraum, wobei auf die spezifischen Eigenschaften des jeweilig genutzen Gerätes geachtet werden muss.&lt;br /&gt;
&lt;br /&gt;
== Farbraumspaß ==&lt;br /&gt;
Wir wollen uns hier ein wenig mit den Möglichkeiten des HSV Farbraumes vertraut machen und einige Spielereien ausprobieren. &lt;br /&gt;
=== Vergrauen ===&lt;br /&gt;
Im HSV Farbraum kann man ein Bild sehr einfach in ein Graustufenbild umwandeln, indem man die Sättigung auf 0 stellt:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Rothsee_farbig.png|center]]&lt;br /&gt;
[[Bild:Farbräume_Rothsee_grau.png|center]]&lt;br /&gt;
&lt;br /&gt;
Wenn einem reines S/W zu langweilig ist, kann man auch ein feste Sättigung und Farbe vorgeben, so daß das Bild eingefärbt wird ( S/W-Foto-Material verändert häufig mit dem Alter ein wenig seine Farbe oder ist von vornherein leicht farbig ). Wer Spaß an dieser Art der Bildbearbeitung findet, kann auch noch die Helligkeit anpassen - Schwarzweißfilme sind nach Wellenlängen unterschiedlich empfindlich. Blau wird auf dem positiv häufig heller wiedergegeben als grün, welches wiederum heller als rot erscheint. Viel Spaß beim ausprobieren.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Rothsee_blackwhitestyle.png|center]]&lt;br /&gt;
&lt;br /&gt;
=== Farbkurven ===&lt;br /&gt;
Wer sich einmal mit einem Bildbearbeitungsprogramm auseinandergesetzt hat, wird sie kennen, die Dialoge zum Verändern der Farbkurven. Die Kurven stellen eine Verschiebungsfunktion dar: Hat man z.B. ein Farbkurve für den roten Farbkanal festgelegt, so beschreibt die Farbkurve f an einer Stelle i den Wert, den ein Punkte im roten Farbkanal hat, wenn er vorher den Wert i hatte, also:&lt;br /&gt;
 Punkt.rot = f(Punkt.rot);&lt;br /&gt;
im Bild: GIMP:&lt;br /&gt;
[[Bild:Farbräume_GIMPColorcurvesdialog.png|center]]&lt;br /&gt;
Diese Idee wollen wir uns zu Eigen machen - so ist es im HSV Farbraum nur zu konsequent, nicht Rot/Grün/Blau, bzw. Cyan/Magenta/Gelb sondern die Hue, Saturation und Value Werte zu manipulieren. Und die Sache ein wenig auf die Spitze zu treiben, wollen wir uns nicht nur mit Hue/Hue und den 2 anderen Kurven beschäftigen, sondern auch mit gemischten, bei denen sich anhand der Farbe die Helligkeit oder Sättigung ändert. Vieles ist hier denkbar.&lt;br /&gt;
&lt;br /&gt;
Um es realisieren zu können, benötigt man zuerst einmal eine eigene Dialogbox, die das Bearbeiten von (Farb-)Kurven zulässt. Im wesentlichen dürfte das niemanden hier überfordern - ich empfehle folgende Szenerie: Die Kurve wird mithilfe von Spline-Interpolation erzeugt. Die Menge der Stützstellen ist im wesentlichen beliebig, für einige Kurven ist es jedoch wichtig, nicht nur natürliche, sondern auch periodische Kurven erzeugen zu können. Genauere Informationen hierzu finden sich in den Literaturangaben.&lt;br /&gt;
&lt;br /&gt;
Die einfachste Art der Kurven ist wie gesagt die, die sich selber beeinflussen. So lassen sich leicht Farben durch andere Farben tauschen, ohne den Rest der Farben zu beeinflussen. Man kann natürlich auch bestimmte Sättigungen hervorheben (also Sättigung/Sättigung statt bei Farben Hue/Hue) oder ähnliches. Als Beispiel wird der Hue-Bereich von Gelb in den von Rot verschoben. Durch feine Abstimmung lässt sich erreichen, daß andere Farben sich dabei nicht verändern (Diesen Effekt kann man noch leicht in Photoshop erreichen, man muss jedoch für jede Farbe getrennt vorgehen, falls man verschiedene Farben verändern möchte: Image/Adjustmennts/Hue-Saturations . Wir können dagegen leicht mehrere Farben auf einmal austauschen.).&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Hue_Hue_mapping.png|center]]&lt;br /&gt;
&lt;br /&gt;
Als Alternative noch eine Sättigung/Sättigung Variante des obigen Bildes. Links wurde die 20. Wurzel aus der Sättigung gezogen, rechts wurde die Sättigung zur 4. Potenz erhoben (dies entspricht einer Erniedrigung bzw. Erhöhung des Sättigungkontrastes). Die einstellbaren Kurven lassen sich dazu natürlich genauso benutzen, aber so sparen wir uns ein paar Bilder ;-)&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Sat_Sat_mapping.png|center]]&lt;br /&gt;
&lt;br /&gt;
Nun wollen wir einmal eine Value/Hue Variante betrachten. Ziel ist es, ein Pixel anhand seines Value den Hue weiterzudrehen. Man trägt im Kurvendialog wie folgt an: In Y-Richtung variiert die Hue, in X-Richtung ist Value von 0 bis 1 angetragen. Zu einer bestimmten Value soll also der Hue um einen bestimmten Winkel weitergedreht werden - vorwärts und rückwärtsdrehen sollte möglich sein. Rechnen könnte man dann:&lt;br /&gt;
&lt;br /&gt;
 Pixel.Hue = Pixel.Hue + Kurve(Pixel.Value);&lt;br /&gt;
&lt;br /&gt;
Da Pixel.Hue dadurch auch negative oder zu große Werte annehmen kann, sollte man sie wieder auf den Berech 0 bis 2*Pi zurückrechnen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Farbräume_Val_Hue_mapping.png|center]]&lt;br /&gt;
&lt;br /&gt;
Im obigen Bild ist die zugrundeliegende Kurve die [http://de.wikipedia.org/wiki/Glockenkurve Gaussche Glockenkurve] mit sigma = 0.29, mu = 0.9, d.h. also, daß bei niedrigen value Werten im wesentlichen keine Veränderung des Hue passiert. Je heller die Szene jedoch wird, desto stärker verschiebt sich der Farbton. Da die Lichtquelle im Hintergrund des Fotos ist, verändern sich die Farben stärker, je weiter hinten sich die Luftballons befinden.&lt;br /&gt;
&lt;br /&gt;
Es lassen sich noch einige weitere Varianten vorstellen, als die, die hier gezeigt wurden. So könnte man anhand einer Hue/Sat Kurve bestimmte Farben vergrauen lassen und andere hervorheben - der Effekt ist sicherlich nicht gänzlich unbekannt. In der Fotografie wird gerne entsprechend manipuliert: Man stelle sich ein Mädchen vor, das eine rote Rose hält. Alle Farben sind grau, nur die Blüte der Rose ist rot - mit Hue/Sat Kurven ist das wirklich sehr leicht zu erreichen.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* [http://www.efg2.com/Lab/Graphics/Colors/index.html Earl F. Glynn II: efg's Palettes and Colors Lab]&lt;br /&gt;
* [http://www.efg2.com/Lab/Library/Color/index.html Earl F. Glynn II: efg's Color Reference Library]&lt;br /&gt;
* [http://www.midnightkite.com/color.html Dan Bruton: Color Science]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Color_model Englische Wikipedia: Color Models. Viele informationen, Veranschaulichungen, Umrechnungsformeln]&lt;br /&gt;
* [http://www.adhocconference.com/cgi-bin/blosxom.cgi/PastShows/MacHack16/2001_papers.html Darrin Cardani: Adventures in HSV Space (als PDF)]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Spline-Interpolation Wikipedia: Spline interpolation]&lt;br /&gt;
* Bronstein, Semendjajew, Musiol, Mühlig: Taschenbuch der Mathematik. 5 Auflage. S.955: 19.7.1 Kubische Splines&lt;br /&gt;
* [http://www.arndt-bruenner.de/mathe/scripts/kubspline.htm Arndt Brünner: Kubische Splines]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Link&amp;diff=16624</id>
		<title>Link</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Link&amp;diff=16624"/>
				<updated>2006-03-16T10:35:14Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* OpenGL */&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 =&lt;br /&gt;
Hier finden Sie eine Übersicht von Links. &lt;br /&gt;
&lt;br /&gt;
*Weitere Navigations Links findet ihr 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;
{|{{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;
{|{{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.informatik.fh-muenchen.de/~schieder/opengl-ss99/index.html FH Muenchen]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Eine Art riesiges OpenGL Tutorial von mehren Autoren&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.informatik.fh-muenchen.de/~schieder/graphik-01-02/index.html FH Muenchen]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Begleit Script von Prof. Dr. R. Schiedermeier ueber Computergrafik.&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://www.husser.de/index.php?site=content&amp;amp;action=overview&amp;amp;id=2 Husser.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.dcw-group.net/index.php?menue=cod&amp;amp;site=tuts/coding/oglkurs/index dcw-group.net]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Hier findet ihr einige OpenGL Tutorials die primär an OpenGL-Anfänger gerichtet sind. Der Autor dieser Artikel ist auch im DelphiGL Forum anzutreffen. Sprache der Wahl ist hier Delphi.&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;
|&lt;br /&gt;
|-&lt;br /&gt;
|[http://people.fh-landshut.de/~gschied/opengl/ FH Landshut]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|&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;
=== Textur Erstellung ===&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;
|[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://www.frakes.de/gimp-tutorials/texturen/index.html frakes.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;
{|{{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.serverpool.org/f/viewtopic.php?t=5786 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Ein Thread im Forum von [http://blendpolis.serverpool.org Blendpolis] in dem '''sehr''' viele Tutorials aufgelistet sind&lt;br /&gt;
|-&lt;br /&gt;
|[http://blendpolis.serverpool.org/f/article_cat.php?fldAuto=7 Blendpolis]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Eigentliche Tutorial Seite von [http://blendpolis.serverpool.org Blendpolis] die Auswahl ist hier aber nicht so groß&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.trcoding.de/informatik/blender/index.html trcoding.de]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Auf dieser Seite findet ihr ein großes Blender Turorial, welches an Blender Anfänger gerichtet ist&lt;br /&gt;
|-&lt;br /&gt;
|[http://blender3d.org/cms/Getting_Started.246.0.html 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;
&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;
{|{{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/html/gl/ 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;
{|{{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;
{|{{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;
{|{{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;
{|{{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;
{|{{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;
{|{{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;
{|{{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/features/20040526/james_01.shtml 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;
{|{{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.blochi.com/HDRI/ blochi.com]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
|Diplomarbeit, beschreibt umfangreich, was überhaupt HDR ist, geht darauf ein, wie man HDR Bilder mit verschiedenen Tools erzeugt, und zeigt Beispiele auf, wie HDR im CG Bereich Anwendung findet. Hier wird jedoch keine mathematische Theorie dazu vermittelt. &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;
{|{{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;
{|{{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;
{|{{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.delphi3d.net/articles/viewarticle.php?article=terraintex.htm Delphi3D]&lt;br /&gt;
|{{Englisch}}&lt;br /&gt;
|Terraintexturierung. Hier hab ich es gelernt. Man sollte nur die Coverage-Faktoren in eine Textur stecken, dann verträgt es sich mit LODing besser. &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;
{|{{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://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;
{|{{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;
|[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;
{|{{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.com/launcher.php?em=links alte Link Seite]&lt;br /&gt;
|{{Deutsch}}&lt;br /&gt;
| Die alte Link Seite von DelphiGL.com.(Diese hier ist aktueller)&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;
|-&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;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Bilder_als_Ressourcen&amp;diff=16603</id>
		<title>Bilder als Ressourcen</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Bilder_als_Ressourcen&amp;diff=16603"/>
				<updated>2006-03-13T15:38:12Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Ressourcen laden */ Code angepasst&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Vorwort==&lt;br /&gt;
Eins vorneweg: Da ich noch OpenGL-Frischling bin, sollten die in diesem Artikel beschriebenen Methoden zwar funktionieren, jedoch bin ich fast der Überzeugung, dass sie Speicher- sowie Performancetechnisch eher miserabel sind...&lt;br /&gt;
&lt;br /&gt;
==Einleitung==&lt;br /&gt;
Man kann Bilder (und auch jeglichen anderen Daten) beispielsweise in Ressourcen-Dateien packen,&lt;br /&gt;
um die .exe möglichst klein zu halten.&amp;lt;br&amp;gt;&lt;br /&gt;
Oder aber man freut sich, wenn man immer alle Grafiken in einer Datei zusammen hat.&amp;lt;br&amp;gt;&lt;br /&gt;
Oder man verwendet Ressourcen-Dateien, damit &amp;quot;net jeder Wald und Wiesendepp mit Paint die Grafiken verunstalten kann&amp;quot; (Zitat Flash)&lt;br /&gt;
&lt;br /&gt;
Warum auch immer man sich für Ressourcen-Dateien entscheiden sollte, die Herangehensweise ist die selbe - nämlich folgende:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==.RES Datei Erstellen...==&lt;br /&gt;
Als erstes nehmen wir alle Grafiken, die wir brauchen, und packen sie in eine .res Datei.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;quot;packen&amp;quot; weckt hier möglicherweise falsche Hoffnungen, denn die Daten werden dadurch nicht komprimiert, sie kommen bloß alle zusammen in eine Datei.&amp;lt;br&amp;gt;&lt;br /&gt;
Um eine solche .res Datei zu erschaffen gibt es mehrere Wege - hier sind zwei:&lt;br /&gt;
&lt;br /&gt;
===einfach und schnell===&lt;br /&gt;
Man benutzt das Programm &amp;quot;PE Resource Explorer&amp;quot;, mit welchem man sich recht bequem seine Resourcen zusammen klicken kann. (Download: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm)&lt;br /&gt;
&lt;br /&gt;
===selber tippen===&lt;br /&gt;
Die andere Möglichkeit ist etwas mehr Arbeit: Also schnappst du dir Notepad oder sonst irgendeinen Editor und erstellst eine Datei mit folgendem Format:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;Ressourcenbezeichner&amp;gt; &amp;lt;Resourcentyp&amp;gt; &amp;lt;Pfad zur Datei&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
beispielsweise:&amp;lt;br&amp;gt;&lt;br /&gt;
myCharTex BITMAP char.tga&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:'''Ressourcenbezeichner:''' ist der Name, den du der Ressource gibst. Statt einem String kannst du auch ne Zahl hinschreiben, also:&lt;br /&gt;
:10 BITMAP holla.bmp&lt;br /&gt;
:Muss man selber wissen, ob man lieber mit Strings oder Integers als Bezeichner arbeitet, hat bestimmt beides Vorzüge...&lt;br /&gt;
&lt;br /&gt;
:'''Ressourcentyp:''' Es gibt einige vordefinierte Typen (für Bitmaps, Jpgs, Cursor, Icon, usw)&lt;br /&gt;
:Für alle Sachen, die nicht explizit nen eigenen Typ haben gibt es RCDATA&lt;br /&gt;
:Das wär dann wohl allgemeine Datenvielfalt, oder so...&lt;br /&gt;
&lt;br /&gt;
:'''Pfad zur Datei:''' ist selbsterklärend denke ich.&lt;br /&gt;
:Kann sein, dass man Gänsefüsschen setzen muss, keine Ahnung - testen!&lt;br /&gt;
&lt;br /&gt;
Jetzt hast du im Editor zeilenweise deine Ressourcen angegeben und speicherst das Werk erstmal als Datei mit der Endung &amp;quot;.rc&amp;quot; ab.&amp;lt;br&amp;gt;&lt;br /&gt;
Dann gibt es in deinem Delphi Verzeichnis einen Ordner &amp;quot;bin&amp;quot; und in selbigem eine Datei brcc32.exe - die brauchen wir jetzt.&amp;lt;br&amp;gt;&lt;br /&gt;
Die .rc Datei enthält ja nur die Dateinamen zu den Ressourcen die du haben willst. brcc32.exe nimmt sich diese Datei und packt die darin angegebenen Ressourcen in eine .res Datei.&amp;lt;br&amp;gt;&lt;br /&gt;
Dazu ruft man die brcc32 in der Kommandozeile auf und übergibt als Parameter den Pfad zur .rc Datei&amp;lt;br&amp;gt;&lt;br /&gt;
Ipp Zipp Zapp, fertig ist die .res Datei &lt;br /&gt;
&lt;br /&gt;
Dieser zweite Weg ist zwar unter Umständen mehr Arbeit, aber dafür hat man dann auch n bisschen Hintergrundwissen abbekommen - kann ja nicht schaden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==...und einbinden==&lt;br /&gt;
Soweit so gut, wir haben die Resourcen alle in einer .res Datei und binden diese mit {$R lemon.RES} in unser Programm ein...&amp;lt;br&amp;gt;&lt;br /&gt;
HA! Wenn man die .res Datei in das Hauptprojekt eingebunden hätte, wäre sie beim compilieren mit in die .exe hineinkompiliert worden.&amp;lt;br&amp;gt;&lt;br /&gt;
Weil wir das aber nicht wollen, gehen wir her und erstellen in Delphi ein neues DLL Projekt.&amp;lt;br&amp;gt;&lt;br /&gt;
Den vorgeschriebenen Quelltext ersetzen wir mit:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
library lemon;&lt;br /&gt;
&lt;br /&gt;
{$R lemon.RES}&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
end.&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
wobei der Name der Library und &amp;quot;lemon.RES&amp;quot; natürlich auf eure Bedürfnisse angepasst werden sollte.&amp;lt;br&amp;gt;&lt;br /&gt;
Wunderbar, jetzt speichern wir das Projekt, compilieren es und der ein oder andere kann auch &amp;quot;Hosianna&amp;quot; rufen, denn jetzt haben wir eine wunderschöne .dll Datei, die all unsere Resourcen enthält. Und ich denke, jeder gewöhnliche Wald und Wiesen Depp, wird sich denken &amp;quot;Möh? DLL - Wasn datt da? Kann man das essen?? Lass ich mal lieber in Ruhe&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
Hehe, aber wir sind noch nicht am Ziel... wir müssen die Daten ja auch wieder aus der DLL rausbekommen.&lt;br /&gt;
&lt;br /&gt;
==Ressourcen laden==&lt;br /&gt;
Zurück in der Hauptanwendung gehen wir folgendermaßen vor:&amp;lt;br&amp;gt;&lt;br /&gt;
Erstmal brauchen wir eine Variable vom Typen Papst ääh, Cardinal.&amp;lt;br&amp;gt;&lt;br /&gt;
Der weisen wir mittels&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
var h: cardinal;&lt;br /&gt;
h := LoadLibrary('lemon.dll');&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
die eben erstelle DLL Datei zu.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn man jetzt in LoadFromRessource oder ähnlichen Funktionen als Parameter eine Instance angeben sollst, ist das unsere Cardinal Variable, die ja auf die DLL zeigt.&amp;lt;br&amp;gt;&lt;br /&gt;
Bei der glBitmap.pas laden wir allerdings immer aus Streams - und zwar so:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
var myStream: TResourceStream&lt;br /&gt;
var h: Cardinal;&lt;br /&gt;
var foo: TglBitmap2D;&lt;br /&gt;
&lt;br /&gt;
// DLL Laden&lt;br /&gt;
h := LoadLibrary('lemon.dll');&lt;br /&gt;
&lt;br /&gt;
// Texturklasse erstellen&lt;br /&gt;
foo := TglBitmap2D.Create;&lt;br /&gt;
&lt;br /&gt;
// Stream auf eine Resource erstellen&lt;br /&gt;
myStream := TResourceStream.CreateFromID(h, 10, RT_RCDATA);&lt;br /&gt;
try&lt;br /&gt;
  // Bild aus Stream laden&lt;br /&gt;
  foo.LoadFromStream(myStream);&lt;br /&gt;
finally&lt;br /&gt;
  // Stream in jedem Falle wieder frei geben&lt;br /&gt;
  myStream.Free;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
// OpenGL Textur erstellen&lt;br /&gt;
foo.GenTexture;&lt;br /&gt;
&lt;br /&gt;
// DLL Wieder entladen wenn sie nicht mehr gebraucht wird&lt;br /&gt;
FreeLibrary(h);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
damit würden wir aus der Datei lemon.dll eine RCDATA Resource mit dem Bezeichner 10 laden.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn man den Ressourcen String-Namen gegeben hat, benutzt man &amp;quot;Create&amp;quot; statt &amp;quot;CreateFromId&amp;quot; und gibt den String an.&lt;br /&gt;
&lt;br /&gt;
==Nachwort==&lt;br /&gt;
Sohohohoho, ich hoffe, ich habe alles Erwähneswerte erwähnt und wenn es jemandem hilft, dann bin ich mächtig stolz, auch mal ne Antwort gegeben zu haben, statt immer nur zu Fragen.&amp;lt;br&amp;gt;&lt;br /&gt;
Abgesehen davon hoffe ich, dass ich an dieser Stelle Lossy eX für Geduld und Wissen danken darf :)&amp;lt;br&amp;gt;&lt;br /&gt;
Ciao&lt;br /&gt;
&lt;br /&gt;
[[Benutzer:Doppelreim|Doppelreim]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung|Bilder in Ressourcen]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Benutzer:Lossy_eX&amp;diff=16245</id>
		<title>Benutzer:Lossy eX</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Benutzer:Lossy_eX&amp;diff=16245"/>
				<updated>2006-02-10T12:43:11Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Steckbrief =&lt;br /&gt;
&lt;br /&gt;
Name: Steffen Xonna&lt;br /&gt;
&lt;br /&gt;
Nick: Lossy eX&lt;br /&gt;
&lt;br /&gt;
Geb.: 1980&lt;br /&gt;
&lt;br /&gt;
Wohnort: Dortmund&lt;br /&gt;
&lt;br /&gt;
Tätigkeit: Softwareentwickler&lt;br /&gt;
&lt;br /&gt;
Homepage: [http://www.dev-center.de/ www.dev-center.de]&lt;br /&gt;
&lt;br /&gt;
= Werdegang =&lt;br /&gt;
&lt;br /&gt;
Bin eigentlich eher sehr zufällig zu den Computern gekommen. Ursprünglich wollte ich RFT-Mechaniker werden. Da wurde mir aber gesagt, dass ich dazu mindest einen Notendurchschnitt von 1.7 brauchte. Na ja. War nie sonderlich der Fleißigste in der Schule. Nicht, dass ich es nicht könnte hatte nur keinen Bock drauf und habe also auch nicht gelernt. Wie dem auch sei. Es musste also was anderes her. So geschehen hatte ich also die Auswahl zwischen einer schulischen Ausbildung zum Informatikassistent oder eine Ausbildung als KFZ-Mechaniker. Also Malochen bis zum Umfallen. Wofür ich mich entschieden habe könnt ihr euch sicherlich denken. Genau. Für den Informatikassistenten.&lt;br /&gt;
&lt;br /&gt;
Es stellte sich dann auch recht schnell herraus, dass ich auf dem Gebiet der Software Entwicklung eine Art Naturtalent bin. Vorher keine Ahnung vom Rechner gehabt, war ich in der Lage Programme zu schreiben als hätte ich nie etwas anderes getan. Ab diesem Zeitpunkt habe ich dann auch nichts anderes mehr getan. Schon wärend meiner Ausbildung hatte ich in C eine kleine DOS Grafikengine für 2D Spiele geschrieben. Also mit allem Drum und Dran. Na ja. Windows 95 sei Danke konnte ich sie als sie recht weit fortgeschritten war dann auch verschrotten. Was will man schon mit DOS Spielen wenn man Windows Spiele haben kann. *argh*&lt;br /&gt;
&lt;br /&gt;
Seit 1999 durfte ich dann auch endlich profesionell Entwickeln. Leider gingen die Firmen immer in regelmäßigen Abständen insolvent auf dass ich nie irgendwo sesshaft wurde. Aber durch die vielen Ansichten habe ich sehr viele unterschiedliche Bereiche kennengelernt und mein Programmierstil hat sich maßgeblich verändert. Ich bin zu einem Verfechter von OOP gewurden. Allerdings bin ich auch sehr gut in der Lage von OOP abstand zu halten wenn es erforderlich ist. In der letzten Firma bin ich dann eher Notgedrungen an OpenGL geraten und seit her nicht wieder von los gekommen. Aber auch wärend dieser Tätigkeit habe ich sehr viele Grafiken mit der GDI programmiert. &lt;br /&gt;
&lt;br /&gt;
All das formt natürlich ein persönliches Interessengebiet und das liegt bei mir voll und ganz im 2D Bereich. Wie der ein oder andere schon mitbekommen haben dürfte. Und sehr sehr gerne auch selber Grafiken irgendwo im Speicher bearbeiten. Sie wie man es bei der [[Glbitmap_loader|glBitmap]] der Fall ist.&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Team&amp;diff=16244</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Team&amp;diff=16244"/>
				<updated>2006-02-10T12:05:45Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* DGLOpenGL.pas */&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;
= 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}}&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;
*&amp;quot;der Chef&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 des Wikis&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:Nico Michaelis|Nico Michaelis]] &lt;br /&gt;
|{{eMail|delphic|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Magellan|Magellan]] &lt;br /&gt;
|{{eMail|Magellan|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lossy eX|Lossy eX]] &lt;br /&gt;
|{{eMail|Lossy|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*dglOpenGL.pas&lt;br /&gt;
*allgemeine Inhaltliche Kontrolle im Forum&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}}&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:Flo|Flo]]&lt;br /&gt;
|{{eMail|Flo|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:I0n0s|i0n0s]] &lt;br /&gt;
|{{eMail|JonasScholz|web.de}}&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}}&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;
*Muss wohl nichts zu gesagt werden&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}}&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:Flash|Flash]] &lt;br /&gt;
|{{eMail|Flash|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*DGL-Poll pflegen&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}}&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:La Boda|La Boda]]&lt;br /&gt;
|{{eMail| -pdl-|web.de}}&lt;br /&gt;
|&lt;br /&gt;
*Inhaltliche Pflege des Wikis&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Team&amp;diff=16243</id>
		<title>Team</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Team&amp;diff=16243"/>
				<updated>2006-02-10T12:04:37Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* 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;
= 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}}&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;
*&amp;quot;der Chef&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 des Wikis&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:Nico Michaelis|Nico Michaelis]] &lt;br /&gt;
|{{eMail|delphic|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Magellan|Magellan]] &lt;br /&gt;
|{{eMail|Magellan|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:Lossy eX|Lossy eX]] &lt;br /&gt;
|{{eMail|Lossy|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*dglOpenGL.pas&lt;br /&gt;
*allgemeine Inhaltliche Kontrolle im Forum&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}}&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:Flo|Flo]]&lt;br /&gt;
|{{eMail|Flo|DelphiGL.com}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|[[Benutzer:I0n0s|i0n0s]] &lt;br /&gt;
|{{eMail|JonasScholz|web.de}}&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}}&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;
|}&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}}&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:Flash|Flash]] &lt;br /&gt;
|{{eMail|Flash|delphigl.com}}&lt;br /&gt;
|&lt;br /&gt;
*DGL-Poll pflegen&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}}&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:La Boda|La Boda]]&lt;br /&gt;
|{{eMail| -pdl-|web.de}}&lt;br /&gt;
|&lt;br /&gt;
*Inhaltliche Pflege des Wikis&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Selektion&amp;diff=16044</id>
		<title>Selektion</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Selektion&amp;diff=16044"/>
				<updated>2006-01-05T18:45:36Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Hinweis */ Etwas drastischer geschrieben&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was ist das?==&lt;br /&gt;
Die Selektion ist ein bestimmter Rendermodus von '''OpenGL'''. Im Selektionsmodus (der durch [[glRenderMode]] gesetzt wird) werden keine [[Fragment]]e erzeugt und auch keine Änderungen am [[Framebuffer]] durchgeführt. Anstelle dessen werden 4 Werte pro sichtbaren [[Primitive]]n in einen [[glSelectBuffer|Selektions Puffer]] geschrieben. Dieser Puffer muss schon vor dem Aufruf dieser Funktion erstellt worden sein.&lt;br /&gt;
&lt;br /&gt;
Die vier Werte die man pro Primitiven erhält sind:&lt;br /&gt;
# Anzahl der Namen auf dem Stack&lt;br /&gt;
# Kleinster Z-Wert des getroffenen Objektes&lt;br /&gt;
# Größter Z-Wert des getroffenen Objektes&lt;br /&gt;
# Name des Objektes&lt;br /&gt;
&lt;br /&gt;
==Wozu brauch ich das?==&lt;br /&gt;
Für die Interaktion des Nutzers mit der Szene.&lt;br /&gt;
&lt;br /&gt;
==Wie geht das?==&lt;br /&gt;
Durch den Selektionspuffer bekommt man die [[OpenGL Name]]n der Szenen Elemente zurückgeliefert die im Rendermodus GL_RENDER gerendert worden wären. Dies ermöglicht es unter zuhilfenahme von [[gluPickMatrix]] den Bereich um einen Mausklick auszuwerten. Wie das genau funktioniert könnt ihr im Selektionstutorial (siehe Links) nachlesen.&lt;br /&gt;
&lt;br /&gt;
==OpenGL Funktionen==&lt;br /&gt;
Folgende Funktionen haben mit der Selektion zu tun:&lt;br /&gt;
&lt;br /&gt;
[[glRenderMode]], [[glSelectBuffer]], [[glLoadName]], [[gluPickMatrix]], [[Picking]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Hinweis==&lt;br /&gt;
Wärend der Selektion muss die selbe Perspektive ([[gluPerspective]] oder [[glOrtho]]) gesetzt sein wie beim rendern der Ausgabe. Wärend der Selektion darf die Perspektive nicht verändert werden, da das Ergebnis sonst merkwürdig ausfallen würde. Ein setzen des Orthomoduses wärend einer Perspectivenausgabe führt zu eben solchen Problemen. Entweder das Eine oder das Andere.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
===Selektion in 2D (glOrtho)===&lt;br /&gt;
Im OnShow meines Formulares erstelle ich den Kontext. Zum Initialisieren der Ansicht rufe ich die untere Methode auf:&lt;br /&gt;
&amp;lt;pascal&amp;gt;procedure TForm1.FormResize(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  VP: array[0..1] of Integer;&lt;br /&gt;
  newWidth, newHeight: Integer;&lt;br /&gt;
begin&lt;br /&gt;
  if (FInitialised) then begin&lt;br /&gt;
    // Set the viewport for the OpenGL window&lt;br /&gt;
    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, @VP);&lt;br /&gt;
&lt;br /&gt;
    // Dont make the Window to large&lt;br /&gt;
    newWidth :=  Min(VP[0], ClientWidth);&lt;br /&gt;
    newHeight := Min(VP[1], Max(1, ClientHeight));&lt;br /&gt;
&lt;br /&gt;
    // Viewport von OpenGL setzen&lt;br /&gt;
    glViewport(&lt;br /&gt;
      (ClientWidth div 2)  - (newWidth div 2),&lt;br /&gt;
      (ClientHeight div 2) - (newHeight div 2),&lt;br /&gt;
      newWidth,&lt;br /&gt;
      newHeight);&lt;br /&gt;
&lt;br /&gt;
    // Projection matrix&lt;br /&gt;
    glMatrixMode(GL_PROJECTION);&lt;br /&gt;
    glLoadIdentity();&lt;br /&gt;
&lt;br /&gt;
    // Perspektive setzen&lt;br /&gt;
    glOrtho(0, newWidth, newHeight, 0, -1, 1);&lt;br /&gt;
&lt;br /&gt;
    // Modelview Matrix&lt;br /&gt;
    glMatrixMode(GL_MODELVIEW);&lt;br /&gt;
    glLoadIdentity();&lt;br /&gt;
  end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Zeichnen mache ich dann nichts weiter als:&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  Error: Cardinal;&lt;br /&gt;
  RenderMode: Cardinal;&lt;br /&gt;
begin&lt;br /&gt;
  // Go to the model view matrix mode&lt;br /&gt;
  glMatrixMode(GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  // Replaces the current matrix with the identity matrix&lt;br /&gt;
  glLoadIdentity();&lt;br /&gt;
&lt;br /&gt;
  // Clear the color and depth buffers&lt;br /&gt;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
  glGetIntegerv(GL_RENDER_MODE, @RenderMode);&lt;br /&gt;
&lt;br /&gt;
  glPushName(0);&lt;br /&gt;
  glLoadName(10);&lt;br /&gt;
  // Zeichnen&lt;br /&gt;
  glPopName;&lt;br /&gt;
&lt;br /&gt;
  Error := glGetError;&lt;br /&gt;
  if Error &amp;lt;&amp;gt; 0 then&lt;br /&gt;
    Caption := gluErrorString(Error);&lt;br /&gt;
&lt;br /&gt;
  if (RenderMode = GL_RENDER)&lt;br /&gt;
    then SwapBuffers (FDC);&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Selection sieht so aus:&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  Puffer       : array[0..256] of GLUInt;&lt;br /&gt;
  Viewport     : TGLVectori4;&lt;br /&gt;
  Treffer,i    : Integer;&lt;br /&gt;
  Z_Wert       : GLUInt;&lt;br /&gt;
  Getroffen    : GLUInt;&lt;br /&gt;
begin&lt;br /&gt;
  glGetIntegerv(GL_VIEWPORT, @viewport);&lt;br /&gt;
  glSelectBuffer(256, @Puffer);&lt;br /&gt;
  glRenderMode(GL_SELECT);&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode(GL_PROJECTION);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  gluPickMatrix(X, Viewport[3] - Y, 1.0, 1.0, Viewport);&lt;br /&gt;
  glOrtho(0, ClientWidth, ClientHeight, 0, -1, 1);&lt;br /&gt;
&lt;br /&gt;
  FormPaint(Self);&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode(GL_PROJECTION);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  treffer := glRenderMode(GL_RENDER);&lt;br /&gt;
&lt;br /&gt;
  if treffer &amp;gt; 0 then begin&lt;br /&gt;
    Getroffen := High(GLUInt);&lt;br /&gt;
    Z_Wert := High(GLUInt);&lt;br /&gt;
    for i := 0 to Treffer-1 do&lt;br /&gt;
      if Puffer[(i*4)+1] &amp;lt; Z_Wert then begin&lt;br /&gt;
        getroffen := Puffer[(i*4)+3];&lt;br /&gt;
        Z_Wert := Puffer[(i*4)+1];&lt;br /&gt;
      end;&lt;br /&gt;
&lt;br /&gt;
    ShowMessage(IntToStr(Getroffen));&lt;br /&gt;
  end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
[[Tutorial_Selection| Selektionstutorial von DelphiGL.com]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Selektion&amp;diff=16036</id>
		<title>Selektion</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Selektion&amp;diff=16036"/>
				<updated>2006-01-05T12:05:22Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Selektion in 2D (glOrtho) */ Projektion wird jetzt gepushed anstelle es hinterher neu zu setzen. Ist wohl einfacher.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Was ist das?==&lt;br /&gt;
Die Selektion ist ein bestimmter Rendermodus von '''OpenGL'''. Im Selektionsmodus (der durch [[glRenderMode]] gesetzt wird) werden keine [[Fragment]]e erzeugt und auch keine Änderungen am [[Framebuffer]] durchgeführt. Anstelle dessen werden 4 Werte pro sichtbaren [[Primitive]]n in einen [[glSelectBuffer|Selektions Puffer]] geschrieben. Dieser Puffer muss schon vor dem Aufruf dieser Funktion erstellt worden sein.&lt;br /&gt;
&lt;br /&gt;
Die vier Werte die man pro Primitiven erhält sind:&lt;br /&gt;
# Anzahl der Namen auf dem Stack&lt;br /&gt;
# Kleinster Z-Wert des getroffenen Objektes&lt;br /&gt;
# Größter Z-Wert des getroffenen Objektes&lt;br /&gt;
# Name des Objektes&lt;br /&gt;
&lt;br /&gt;
==Wozu brauch ich das?==&lt;br /&gt;
Für die Interaktion des Nutzers mit der Szene.&lt;br /&gt;
&lt;br /&gt;
==Wie geht das?==&lt;br /&gt;
Durch den Selektionspuffer bekommt man die [[OpenGL Name]]n der Szenen Elemente zurückgeliefert die im Rendermodus GL_RENDER gerendert worden wären. Dies ermöglicht es unter zuhilfenahme von [[gluPickMatrix]] den Bereich um einen Mausklick auszuwerten. Wie das genau funktioniert könnt ihr im Selektionstutorial (siehe Links) nachlesen.&lt;br /&gt;
&lt;br /&gt;
==OpenGL Funktionen==&lt;br /&gt;
Folgende Funktionen haben mit der Selektion zu tun:&lt;br /&gt;
&lt;br /&gt;
[[glRenderMode]], [[glSelectBuffer]], [[glLoadName]], [[gluPickMatrix]], [[Picking]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
&lt;br /&gt;
===Selektion in 2D (glOrtho)===&lt;br /&gt;
Im OnShow meines Formulares erstelle ich den Kontext. Zum Initialisieren der Ansicht rufe ich die untere Methode auf:&lt;br /&gt;
&amp;lt;pascal&amp;gt;procedure TForm1.FormResize(Sender: TObject);&lt;br /&gt;
var&lt;br /&gt;
  VP: array[0..1] of Integer;&lt;br /&gt;
  newWidth, newHeight: Integer;&lt;br /&gt;
begin&lt;br /&gt;
  if (FInitialised) then begin&lt;br /&gt;
    // Set the viewport for the OpenGL window&lt;br /&gt;
    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, @VP);&lt;br /&gt;
&lt;br /&gt;
    // Dont make the Window to large&lt;br /&gt;
    newWidth :=  Min(VP[0], ClientWidth);&lt;br /&gt;
    newHeight := Min(VP[1], Max(1, ClientHeight));&lt;br /&gt;
&lt;br /&gt;
    // Viewport von OpenGL setzen&lt;br /&gt;
    glViewport(&lt;br /&gt;
      (ClientWidth div 2)  - (newWidth div 2),&lt;br /&gt;
      (ClientHeight div 2) - (newHeight div 2),&lt;br /&gt;
      newWidth,&lt;br /&gt;
      newHeight);&lt;br /&gt;
&lt;br /&gt;
    // Projection matrix&lt;br /&gt;
    glMatrixMode(GL_PROJECTION);&lt;br /&gt;
    glLoadIdentity();&lt;br /&gt;
&lt;br /&gt;
    // Perspektive setzen&lt;br /&gt;
    glOrtho(0, newWidth, newHeight, 0, -1, 1);&lt;br /&gt;
&lt;br /&gt;
    // Modelview Matrix&lt;br /&gt;
    glMatrixMode(GL_MODELVIEW);&lt;br /&gt;
    glLoadIdentity();&lt;br /&gt;
  end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Zeichnen mache ich dann nichts weiter als:&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  Error: Cardinal;&lt;br /&gt;
  RenderMode: Cardinal;&lt;br /&gt;
begin&lt;br /&gt;
  // Go to the model view matrix mode&lt;br /&gt;
  glMatrixMode(GL_MODELVIEW);&lt;br /&gt;
&lt;br /&gt;
  // Replaces the current matrix with the identity matrix&lt;br /&gt;
  glLoadIdentity();&lt;br /&gt;
&lt;br /&gt;
  // Clear the color and depth buffers&lt;br /&gt;
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
&lt;br /&gt;
  glGetIntegerv(GL_RENDER_MODE, @RenderMode);&lt;br /&gt;
&lt;br /&gt;
  glPushName(0);&lt;br /&gt;
  glLoadName(10);&lt;br /&gt;
  // Zeichnen&lt;br /&gt;
  glPopName;&lt;br /&gt;
&lt;br /&gt;
  Error := glGetError;&lt;br /&gt;
  if Error &amp;lt;&amp;gt; 0 then&lt;br /&gt;
    Caption := gluErrorString(Error);&lt;br /&gt;
&lt;br /&gt;
  if (RenderMode = GL_RENDER)&lt;br /&gt;
    then SwapBuffers (FDC);&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Selection sieht so aus:&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  Puffer       : array[0..256] of GLUInt;&lt;br /&gt;
  Viewport     : TGLVectori4;&lt;br /&gt;
  Treffer,i    : Integer;&lt;br /&gt;
  Z_Wert       : GLUInt;&lt;br /&gt;
  Getroffen    : GLUInt;&lt;br /&gt;
begin&lt;br /&gt;
  glGetIntegerv(GL_VIEWPORT, @viewport);&lt;br /&gt;
  glSelectBuffer(256, @Puffer);&lt;br /&gt;
  glRenderMode(GL_SELECT);&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode(GL_PROJECTION);&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
&lt;br /&gt;
  gluPickMatrix(X, Viewport[3] - Y, 1.0, 1.0, Viewport);&lt;br /&gt;
  glOrtho(0, ClientWidth, ClientHeight, 0, -1, 1);&lt;br /&gt;
&lt;br /&gt;
  FormPaint(Self);&lt;br /&gt;
&lt;br /&gt;
  glMatrixMode(GL_PROJECTION);&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
&lt;br /&gt;
  treffer := glRenderMode(GL_RENDER);&lt;br /&gt;
&lt;br /&gt;
  if treffer &amp;gt; 0 then begin&lt;br /&gt;
    Getroffen := High(GLUInt);&lt;br /&gt;
    Z_Wert := High(GLUInt);&lt;br /&gt;
    for i := 0 to Treffer-1 do&lt;br /&gt;
      if Puffer[(i*4)+1] &amp;lt; Z_Wert then begin&lt;br /&gt;
        getroffen := Puffer[(i*4)+3];&lt;br /&gt;
        Z_Wert := Puffer[(i*4)+1];&lt;br /&gt;
      end;&lt;br /&gt;
&lt;br /&gt;
    ShowMessage(IntToStr(Getroffen));&lt;br /&gt;
  end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
[[Tutorial_Selection| Selektionstutorial von DelphiGL.com]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Tutorial_Komponentenentwicklung&amp;diff=14591</id>
		<title>Diskussion:Tutorial Komponentenentwicklung</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Tutorial_Komponentenentwicklung&amp;diff=14591"/>
				<updated>2005-11-29T12:24:21Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Tutorial ist formal erstmal soweit korrekt, vermittelt aber gegenüber den Einsteiger-Tuts IMHO nichts Neues (oder ich hab das Neue übersehen).&lt;br /&gt;
&lt;br /&gt;
Stellen, an denen Du mehr ins Detail gehen könntest, währen das Beeinflussen des DC (z.B. Skalierung der logischen Pixel-Skala unabhängig von der Fenstergröße, überschreiben von Properties, Implementierung einfacher nicht-visueller Komponenten).&lt;br /&gt;
&lt;br /&gt;
Weiterhin fehlt mir in diesem Tut auch eine gewisse Erklärung von dem, wie Du auf gewisse Source-Zeilen kommst, auch wenn alles dahinter kommentiert ist. Unter einem Tutorial stelle ich mir eine Wissensvermittelnde Erklärung vor, die wesentlich ausführlicher darlegt, wie man sich selbst den vermittelten Gegenstand herleiten kann.&lt;br /&gt;
&lt;br /&gt;
MfG, --[[Benutzer:BenBE|BenBE]] 09:04, 29. Nov 2005 (CET)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Was mir auch gerade in einem anderen Artikel aufgefallen ist. Könntest du zwischen Code und Kommentar bitte mindestens 1 Leerzeichen platz lassen? Ich finde das wirkt so ein wenig globig. Mir persönlich fällt es mit einem Leerzeichen viel leichter den Code zu lesen.&lt;br /&gt;
--[[Lossy eX|Lossy eX]] 13:23, 29. Nov 2005 (CET)&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_Lektion_2&amp;diff=14590</id>
		<title>Tutorial Lektion 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_Lektion_2&amp;diff=14590"/>
				<updated>2005-11-29T12:16:09Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Saubere Arbeit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Entdeckung einer neuen Welt =&lt;br /&gt;
== Vorwort ==&lt;br /&gt;
Ich möchte Euch an dieser Stelle bei DGL herzlich willkommen heißen. Vermutlich wird dies eines der ersten Tutorials sein, das Ihr als Einsteiger lesen werdet. Wahrscheinlich werdet Ihr dann auch noch nicht lange bei uns sein und Euch nicht vorstellen können, dass all die Schreiber auf unserer Seite keine Gurus, sondern ganz normale Menschen sind.&lt;br /&gt;
&lt;br /&gt;
Man kann uns also jeder Zeit im Forum &amp;quot;anfassen&amp;quot;, uns Fragen stellen, Vorschläge unterbreiten oder einfach nur einmal kurz mit einem Lob ermutigen weitere Texte zu verfassen ;-).&lt;br /&gt;
&lt;br /&gt;
Ich wünsche Euch an dieser Stelle viel Erfolg bei dem Einstieg in die Thematik OpenGL und ermahne Euch noch einmal, dass Ihr Eure Ziele nicht zu weit steckt. Wirklich Spaß beginnt OpenGL nämlich erst dann zu machen, wenn man stets kleinere Erfolge feiern kann.&lt;br /&gt;
== Höhere Mächte - Matrizen und ihre Folgen ==&lt;br /&gt;
=== Saubere Arbeit ===&lt;br /&gt;
Bevor wir direkt beginnen etwas zu Zeichnen müssen wir erst einmal das Bild löschen, denn wie in der vorherigen Lektion beschrieben zeichnen wir die Szene jeden Schleifendurchlauf neu. Das Löschen der Puffer, in dem die Bildinformationen enthalten sind übernimmt die Funktion [[glClear]]. Die Farbinformationen unser  [[Fragment|Fragmente]] (Fragmente sind vergleichbar mit den [[Pixel|Pixeln]] auf dem Bildschirm besitzen aber weitere Informationen wie z.B. Tiefenwerte. Bei der Ausgabe des Bildes werden diese Fragmente in Pixel umgewandelt) sind in dem so genannten [[Farbpuffer]] (Colorbuffer) gespeichert. Aus diesem Grund übergeben wir an die Funktion glClear die Konstante GL_COLOR_BUFFER_BIT. Die oben bereits angesprochenen Tiefenwerte stehen im [[Tiefenpuffer]]. Diese Daten werden benutzt um zu entscheiden welche Pixel durch andere verdeckt werden. Deshalb sollten wir den Tiefenpuffer auch mit löschen. Die Konstante dafür heißt GL_DEPTH_BUFFER_BIT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;//Farbbuffer und Tiefenpuffer entleeren&lt;br /&gt;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[bild:tutimg_lektion2_puffereffekt.gif|right]]&lt;br /&gt;
Mit Hilfe des Befehls [[glClearColor]] können wir festlegen, welche Farbinformationen mit dem Aufruf von glClear in den Colorbuffer geschrieben werden sollen. Wenn wir es also genau nehmen so löscht glClear den Colorbuffer nicht, sondern es schreibt ihn mit den definierten Werten voll. Standardmäßig erhalten die Fragmente eine schwarze Farbe. (Der Vollständigkeit halber sei erwähnt, dass der Tiefenpuffer immer mit Nullen überschrieben wird.)&lt;br /&gt;
&lt;br /&gt;
Es wird also nicht bei jedem Zeichenvorgang (Rendervorgang) der Bildspeicher gelöscht, sondern der Programmierer entscheidet, wann dies geschehen soll. Theoretisch könnt Ihr auch die Szene wiedergeben und dann löschen, bevor sie ausgegeben wird... wer's mag :).&lt;br /&gt;
&lt;br /&gt;
Wer sich entscheidet den Colorbuffer nicht zu löschen, der kann so auch einige nette Effekte erzeugen. Den Cheatern unter euch sollte der erreichte Effekt bekannt vorkommen, wenn man beispielsweise bei Counter-Strike durch die Wand gelaufen ist. Der Grund für das Verwischen ist in beiden Fällen derselbe: Das neue Bild wird gezeichnet, ohne dass das alte Bild aus dem Puffer entfernt wurde.&lt;br /&gt;
&lt;br /&gt;
=== Und die Welt ist doch keine Scheibe... ===&lt;br /&gt;
[[bild:tutimg_lektion2_koordinatensystem.jpg|256px|right]]&lt;br /&gt;
Nachdem wir nun wieder Ordnung im Speicher geschafft haben, können wir zum interessanten Teil kommen: &amp;quot;Wie darf man sich einen 3D-Raum vorstellen?&amp;quot; Nun ... warum schaut Ihr Euch nicht einmal in Eurem Zimmer um?&lt;br /&gt;
&lt;br /&gt;
Versuchen wir doch mal, ein Beispiel direkt aus dem Leben gegriffen zu nehmen und stellen uns unsere Umgebung als Koordinaten-System vor (Igitt!). Der Monitor, der hoffentlich direkt vor uns steht, ist in diesem Fall unser Ursprung, d.h. er liegt an dem Punkt (0, 0, 0).&lt;br /&gt;
&lt;br /&gt;
Blicken wir seitwärts neben den Monitor, so sehen wir eine Linie (wenn Ihr es nicht tun solltest, macht Euch keine Sorgen ... solche Anfälle hat der Autor häufiger *g*), die von links nach rechts verläuft. Es handelt sich hierbei um die X-Achse, die links vom Monitor im negativen Bereich verläuft, rechts davon in den positiven.&lt;br /&gt;
&lt;br /&gt;
Nun blicken wir einmal nach oben und einmal nach unten und schon erspähen wir die Y-Achse, die oberhalb des Monitors positiv verläuft, unterhalb negativ. Wunderbar! Wenn Ihr bereits in 2D gearbeitet habt, solltet Ihr an dieser Stelle ein dümmliches Grinsen auf Eurem Gesichte haben und das wohltuende Gefühl, dass Euch das doch alles bereits irgendwie bekannt vorkommt. Doch zu unserem Entsetzen können wir uns ja auch noch von unserem Bildschirm wegbewegen oder auch dichter heran (alle Kurzsichtigen unter uns sollten das nicht so persönlich nehmen, auch sie leben in einem 3D-Raum ^__-).&lt;br /&gt;
&lt;br /&gt;
Dieses Phänomen ist im 3D-Raum typisch, jedoch nicht unerklärlich, da wir uns auf der Z-Achse bewegen. Rollen wir mit dem Stuhl vom Monitor weg, so gelangen wir in den positiven Bereich der Z-Achse, bewegen wir uns drauf zu, gelangen wir in den negativen Bereich. Jeder, der bereits in D3D programmiert hat, sollte sich schleunigst einprägen, dass das ein großer Unterschied zwischen D3D und OpenGL ist. Das kann sonst zu einigen wirklich fiesen Fehlern führen, wenn man es nicht weiß... *fg*.&lt;br /&gt;
&lt;br /&gt;
Soweit so gut! Klingt bisher hoffentlich immer noch nicht so kompliziert. Nur keine Sorge, das Niveau versuchen wir zu halten ;).&lt;br /&gt;
&lt;br /&gt;
Speziell wenn Ihr bereits 2D-Spiele programmiert habt, solltet Ihr Euch sehr schnell von folgenden Gedanken trennen: Die Koordinaten, die Ihr seht und angebt, entsprechen in der Regel nicht den Pixeln des Bildschirmes, sondern so genannten Weltkoordinaten. Eine Definition für diese Weltkoordinaten gibt es nicht, denn wie groß diese sind ist dem Programmierer überlassen. Ob Ihr euer Objekt eine Einheit vor Euch und 0,1 Einheit rechts von Euch oder aber 100 Einheiten vor euch und 10 Einheiten neben Euch positioniert ist egal. Die euch zur Verfügung stehende Welt ist grenzenlos ;). Ihr könnt Eure Szene theoretisch unendlich klein oder aber unendlich groß darstellen. Das einzige was euch wirklich daran hindert ist die Größe und Auflösung der Euch zur Verfügung stehenden Typen wie Integer oder Single ;). Der eigentliche Größeneindruck eines Objektes entsteht durch die Geschwindigkeit mit der sich der Betrachter und andere Objekte in der Welt bewegen.&lt;br /&gt;
&lt;br /&gt;
=== Der erste Kontakt ===&lt;br /&gt;
Um nun etwas mit OpenGL rendern zu können, müssen wir uns bewusst werden, was die Worldmatrix ist. In dieser Matrix wird festgehalten, wie und wo ein Objekt gezeichnet wird. Das hört sich vielleicht zunächst recht merkwürdig an, lässt sich aber leicht veranschaulichen.&lt;br /&gt;
&lt;br /&gt;
Stellen wir uns vor, die Worldmatrix zeigt auf einen Punkt, an dem ein Objekt gezeichnet werden soll (ganz übel... wir werden später detaillierter darauf eingehen. Sollte es jemand also nach der folgenden Erläuterung nicht verstanden haben, kann er mich selbstverständlich persönlich per Mail zur &amp;quot;Rechenschaft&amp;quot; ziehen oder aber er wirft einen Blick in unser OpenGLWiki :)).&lt;br /&gt;
&lt;br /&gt;
Diesen Punkt setzen wir nun am Anfang in den Mittelpunkt unseres Koordinatensystems. Um oberes Beispiel aufzugreifen: Den Bildschirm. Dies geschieht mit dem Befehl [[glLoadIdentity]] und entspricht einem Reset der Worldmatrix. Theoretisch können wir nun an dieser Stelle etwas zeichnen. Dies würde allerdings dazu führen, dass das Objekt sehr groß oder gar nicht zu sehen ist, weil wir uns eben auch an diesen Stellen befinden. Gehen wir doch einmal 1,5 Einheiten nach links und 6 Einheiten nach hinten!&lt;br /&gt;
&lt;br /&gt;
Hierfür sollte man sich bewusst werden, dass wir in OpenGL praktisch an einen Stuhl gefesselt sind, d.h. wir können uns gar nicht bewegen. Das soll uns aber nicht davon abhalten. Wir brauchen ja nur die ganze Welt so zu bewegen, dass es für uns aussieht, als ob wir uns bewegen. Denn wenn sich alles außer uns nach links bewegt, haben wir den Eindruck, wir wären nach rechts gewandert, right?&lt;br /&gt;
&lt;br /&gt;
Nun aber zu der Bewegung unseres ersten Objektes:&lt;br /&gt;
&amp;lt;pascal&amp;gt;glTranslatef(-1.5,0,0);&lt;br /&gt;
glTranslatef(0, 0,-6);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Dies hat bewirkt, dass sich unser Zeichenstift 1,5 Einheiten nach links (negativer Bereich der X-Achse) und anschließend 6Einheiten nach hinten bewegt hat. Ich habe diesen Fall absichtlich in zwei Schritten gefasst, um es zu verdeutlichen. Sicherlich wäre es einfacher, alles mit nur einem Aufruf von [[glTranslate|glTranslate*]] zu machen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;glTranslatef(-1.5, 0,-6);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Man beachte, dass in diesem Fall die 6 Schritte nach hinten notwendig sind um ein bisschen Distanz zum Objekt zu bekommen und nicht direkt in ihm zu stehen!&lt;br /&gt;
&lt;br /&gt;
Fertig! Schon haben wir dort unseren &amp;quot;Zeichenstift&amp;quot; positioniert, der nun auf weitere Zeichenkommandos von uns wartet. Das mag sicherlich alles ein wenig verwirrend klingen... testet es am Besten aus und spielt mit den Parametern und erkennt, was gemeint ist :).&lt;br /&gt;
== Von Sichtungen... ==&lt;br /&gt;
=== Die Büchse der Pandora ===&lt;br /&gt;
Nun sind wir aber auch alle scharf darauf, endlich etwas zu rendern und auf dem Bildschirm auszugeben. Dies geschieht z.B. mit folgenden Zeilen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;glBegin(GL_TRIANGLES);&lt;br /&gt;
  glVertex3f(-1,-1, 0);  &lt;br /&gt;
  glVertex3f( 1,-1, 0);&lt;br /&gt;
  glVertex3f( 0, 1, 0);&lt;br /&gt;
glEnd;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Wir erkennen hierbei eindeutig eine Art Block. Gerade wir Pascaler sollten diese ja lieben :-&amp;gt;. Wir teilen OpenGL mit Hilfe von [[glBegin]] mit, dass wir ein Objekt zeichnen wollen. In diesem Fall übergeben wir den Parameter GL_TRIANGLE, der OpenGL angibt, dass folgende Punkte als ein Dreieck interpretiert werden sollen.&lt;br /&gt;
&lt;br /&gt;
Anschließend folgt ein dreifacher Aufruf von [[glVertex|glVertex3f]]. Jeder Aufruf erzeugt nun einen Punkt (Vertex) in unserem 3D-Raum. Da wir OpenGL bei glBegin mitgeteilt haben, dass diese Punkte zu einem Dreieck zusammengefügt werden sollen wird das auch so getan ;).&lt;br /&gt;
&lt;br /&gt;
Wie wir auf dem Bild erkennen können, wurde unser Dreieck wie erwartet nach links verschoben abgebildet und auch mit einem leichten Abstand zur Kamera, nämlich 6 Einheiten entlang der Z-Achse.&lt;br /&gt;
=== Guter Stoff! ===&lt;br /&gt;
Nun ... ein wenig trostlos sieht unser Dreieck nun doch aus, oder? Ich habe übrigens damals bei D3D rund eine Woche benötigt, bis ich ein schwarzes Dreieck hatte. Wir haben immerhin schon ein weißes ... aber wir gehen nun einen Schritt weiter und werden das Dreieck schön bunt einfärben.&lt;br /&gt;
&lt;br /&gt;
Bevor nun irgendjemand anfängt und Pixel für Pixel den Bildschirm nach zu pinseln oder gar sein PaintShop bereits offen hat, um die ersten Texturen zu erstellen, sei gestoppt! Es gibt für einfache Einfärbungen in OpenGL eine bessere Methode. Wir definieren einfach für jeden Eckpunkt eine Farbe und OpenGL wird dann sogar eigenständig die Farbverläufe dafür erstellen. Jeder der D3D kennt, wird diese Vorgehensweise bekannt vorkommen und er wird beginnen verzweifelt nach dem FVF zu suchen, um es korrekt zu definieren... Wenn Ihr einen Vertex zeichnet, so rendert OpenGL diesen automatisch &amp;quot;weiß&amp;quot; (Ah huch! Deswegen ist unser Dreieck auch weiß???). Alles was wir nun machen müssen, ist OpenGL mitzuteilen, dass es eine andere Farbe einsetzen soll. Und zwar wird OpenGL diese Farbe für alle folgenden Eckpunkte nutzen, so lange bis von uns ein anderes Kommando kommt.&lt;br /&gt;
&lt;br /&gt;
Der mysteriöse Befehl, um den ich nun schon die ganze Zeit herumschwafle ist [[glColor|glColor*]]:&lt;br /&gt;
&amp;lt;pascal&amp;gt;// Alle folgenden Eckpunkte werden rot gefärbt&lt;br /&gt;
glColor3f(1,0,0);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Wobei jeder Parameter einen Farbwert repräsentiert und zwar nach dem Muster RGB. Es wird ein Wert zwischen 1 und 0 erwartet, wobei eine Eins &amp;quot;volle Farbsättigung&amp;quot; bedeutet. Das heißt in unserem Fall haben wir als Farbe &amp;quot;rot&amp;quot; gesetzt.&lt;br /&gt;
&lt;br /&gt;
Und weil wir schließlich die Welt ein wenig bunter machen und nicht nur das weiße Dreieck rot färben wollten, werden wir nach jedem Eckpunkt eine neue Farbe setzen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;glBegin(GL_TRIANGLES);&lt;br /&gt;
  glColor3f(1, 0, 0); glVertex3f(-1,-1, 0);  &lt;br /&gt;
  glColor3f(0, 0, 1); glVertex3f( 1,-1, 0);&lt;br /&gt;
  glColor3f(0, 1, 0); glVertex3f( 0, 1, 0);&lt;br /&gt;
glEnd;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Und dies ist dann unser farbenfrohes Ergebnis. Beeindruckend, wenn man bedenkt, wie wenig Aufwand letztendlich dahinter steckt, oder?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[bild:tutimg_lektion2_dreieck.gif]]&lt;br /&gt;
&lt;br /&gt;
== Nachwort ==&lt;br /&gt;
Wer meine Tutorials kennt weiß, dass zum Abschluß noch immer ein wenig Geblubber von mir kommt (man beachte diese entzückende Wortwahl von meiner einer... hoffe, der Lektor findet es auch amüsant...). (Anm. des Lektors: Und wie!) Schauen wir doch mal stolz auf das zurück, was wir heute erreicht haben! Wir haben OpenGL initialisiert, ein erstes Dreieck auf den Bildschirm gezaubert und dieses in den Farbtopf gesteckt! Das solltet Ihr als ein historisches Ereignis ansehen. Als ich damals mit D3D angefangen habe, brauchte ich, um es mir selbst zu erarbeiten, ca. eine Woche (Das ist jetzt der Moment, in dem Ihr Eure Hände heben solltest und ein lautes &amp;quot;Call me God&amp;quot; aus Euch herauskommen sollte, so dass zumindest Eure unmittelbaren Mitmenschen denken, dass Ihr einen Dachschaden habt!!! Das gehört einfach mit dazu ^__- )&lt;br /&gt;
&lt;br /&gt;
Wie immer solltet Ihr Euch nun hinsetzen und Euch ein wenig mit den Parametern vertraut machen. Speziell bei glTranslate* solltet Ihr ein wenig mit den Parametern experimentieren, damit Ihr seht, was es mit den Matrizen auf sich hat und wie diese funktionieren. Wenn Ihr dann auch denkt, dass Ihr damit vertraut seid, versucht ein wenig mit den einzelnen Vertexpositionen zu experimentieren und verändert diese. Wenn auch das klar ist, setzt Euch in die Ecke und warte sehnsüchtig auf mehr von uns :D! (Anm: die &amp;quot;Ecke&amp;quot; ist nicht die Kneipe nebenan ... :)&lt;br /&gt;
&lt;br /&gt;
Im nächsten Kapitel werden wir dann Matrizen-Hardcore machen ... legt also schon mal Euer Aspirin parat, es wird witzig werden *grunz* :).&lt;br /&gt;
&lt;br /&gt;
Und wie immer freuen wir uns sehr über Feedback. Schreibt uns doch einfach ein paar Worte in unser [http://www.delphigl.com/forum/viewforum.php?f=8 Feedback-Forum]. Sagt was Ihr gut und was hingegen Ihr als schlecht empfunden habt! Auch freuen wir uns immer über Ideen für weitere Tutorials, teilt uns also bitte Eure Ideen mit ;)!&lt;br /&gt;
&lt;br /&gt;
Okay... ich wünsche Euch einen angenehmen Tag / Nacht!&lt;br /&gt;
&lt;br /&gt;
'''Euer'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''Phobeus'''&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION | [[Tutorial_lektion1]] | [[Tutorial_lektion3]]}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorial|Lektion2]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=wglUseFontBitmaps&amp;diff=14589</id>
		<title>wglUseFontBitmaps</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=wglUseFontBitmaps&amp;diff=14589"/>
				<updated>2005-11-29T12:14:16Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Beispiel */ Quellcode aufgeräumt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= wglUseFontBitmaps =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Name ==&lt;br /&gt;
'''wglUseFontBitmaps''' - Erzeugt aus der Schrifteinstellungen des [[Device Context]] eine Reihe von [[glBitmap]] Befehlen für die Buchstaben und speichert diese in [[Displaylisten]].&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;function&amp;lt;/b&amp;gt; wglUseFontBitmaps (&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DC&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;: HDC; &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;first&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;count&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;listBase&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;: DWORD): BOOL;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''DC''&lt;br /&gt;
| Ein Display Context mit entsprechenden Font-Einstellungen.&lt;br /&gt;
|-&lt;br /&gt;
! ''first''&lt;br /&gt;
| Mit welchen Zeichen soll begonnen werden&lt;br /&gt;
|-&lt;br /&gt;
! ''count''&lt;br /&gt;
| Anzahl der zu erzeugenden Listen/Zeichen&lt;br /&gt;
|-&lt;br /&gt;
! ''listBase''&lt;br /&gt;
| Der Name/Index der Liste für das erste Zeichen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Die Schrifteinstellungen des [[Display Context]]es werden genutzt, um mit [[glBitmap]]-Befehlen die angebenen Zeichen in [[Displaylisten]] zu speichern.&lt;br /&gt;
Wenn ein Fehler auftritt wird statt '''true''', '''false''' zurückgegeben und der Fehler kann über GetLastError abgerufen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Jede Display Liste erhält logischerweise nur einen [[glBitmap]] Aufruf.&lt;br /&gt;
&lt;br /&gt;
Da der [[glBitmap]] Befehl genutzt wird ändert sich die Rasterposition nach aufruf einer Liste.&lt;br /&gt;
&lt;br /&gt;
Falls für ein Zeichen in der gewählten Schrift keine Daten vorliegen wird für dieses Zeichen eine leere Displayliste zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Die durch diese Funktion unter Windows zur Verfügung stehende Schrift hat eine festgelegte Größe und ist logischerweise nur 2D. Möchte man eine 3D-Schrift haben so kann man dafür den Befehl [[wglUseFontOutlines]] benutzen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
&lt;br /&gt;
Zum Erstellen der Bitmapfonts gibt es wie üblich mehrere Wege. Einmal den Weg direkt über die Windowsapi oder den Weg über die Delphiklasse TFont. Das Zeichnen bleibt bei beiden gleich. Aus diesem Grund ist es auch vom Rest ein wenig getrennt.&lt;br /&gt;
&lt;br /&gt;
=== Procedural ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   FontLists: Cardinal;&lt;br /&gt;
 &amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure &amp;lt;/b&amp;gt;CreateLists; &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Wird einmal am Anfang aufgerufen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   CustomFont: HFont;&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&lt;br /&gt;
   &amp;lt;/b&amp;gt;FontLists := glGenLists(&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;256&amp;lt;/font&amp;gt;);&lt;br /&gt;
   &amp;lt;br&amp;gt;&lt;br /&gt;
   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// CustomFont := GetStockObject (SYSTEM_FONT);&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Eine Alternative mit der man die Systemschriftart zurück bekommt.&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;br&amp;gt;&lt;br /&gt;
   CustomFont := CreateFont(&lt;br /&gt;
                            &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;32&amp;lt;/font&amp;gt;,                  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// H&amp;amp;ouml;he&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            0,                   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Breite 0=Keine Vorgabe&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            0,&lt;br /&gt;
                            0,&lt;br /&gt;
                            0,                   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Fett?&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            0,                   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Kursiv?&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            0,                   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Unterstrichen?&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            0,                   &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Durchgestrichen?&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
                            ANSI_CHARSET,&lt;br /&gt;
                            OUT_TT_PRECIS,&lt;br /&gt;
                            CLIP_DEFAULT_PRECIS,&lt;br /&gt;
                            NONANTIALIASED_QUALITY,&lt;br /&gt;
                            FF_DONTCARE &amp;lt;b&amp;gt;or &amp;lt;/b&amp;gt;DEFAULT_PITCH,&lt;br /&gt;
                            &amp;lt;font color=&amp;quot;#FF2222&amp;quot;&amp;gt;'Times New Roman'&amp;lt;/font&amp;gt;);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Name der Schrift&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;br&amp;gt;&lt;br /&gt;
   SelectObject(DC, CustomFont);               &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Font auf einen Device Context benutzen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   wglUseFontBitmaps (DC, 0, 255, FontLists);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Mit selektiertem Font Zeichen erstellen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end&amp;lt;/b&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
=== Objekt orientiert ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Font: TFont;&lt;br /&gt;
 &amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure &amp;lt;/b&amp;gt;CreateLists; &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Wird einmal am Anfang aufgerufen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   CustomFont: HFont;&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&lt;br /&gt;
   &amp;lt;/b&amp;gt;FontLists := glGenLists(&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;256&amp;lt;/font&amp;gt;);&lt;br /&gt;
   &amp;lt;br&amp;gt;&lt;br /&gt;
   Font := TFont.Create;  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Instanz einer Fontklasse erstellen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;try&amp;lt;/b&amp;gt;&lt;br /&gt;
     Font.Name := 'Times New Roman'; &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Name&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     Font.Size := 32;                &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Schriftgröße&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     Font.Style := [fsBold];         &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Styles (fsBold, fsItalic, ...)&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     &amp;lt;br&amp;gt;&lt;br /&gt;
     SelectObject(DC, Font.Handle);              &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Font auf einen Device Context benutzen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
     wglUseFontBitmaps (DC, 0, 255, FontLists);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Mit selektiertem Font Zeichen erstellen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;finally&amp;lt;/b&amp;gt;&lt;br /&gt;
     FreeAndNil(Font);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// erstellte Instanz wieder frei geben&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;end&amp;lt;/b&amp;gt;;&lt;br /&gt;
 &amp;lt;b&amp;gt;end&amp;lt;/b&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
=== Bitmapfonts benutzen ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; ShowText(pText: &amp;lt;b&amp;gt;String&amp;lt;/b&amp;gt;);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&lt;br /&gt;
    &amp;lt;/b&amp;gt;glListBase(FontLists);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Liste auswählen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
    glCallLists(Length(pText), GL_UNSIGNED_BYTE, Pointer(pText));  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Entsprechende Listen aufrufen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end&amp;lt;/b&amp;gt;;&lt;br /&gt;
 &amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure &amp;lt;/b&amp;gt;Draw;  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Zeichen Routine&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   glClear(GL_COLOR_BUFFER_BIT &amp;lt;b&amp;gt;or &amp;lt;/b&amp;gt;GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
   glColor3f(1,0.5,0);        &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Aktuelle Farbe f&amp;amp;uuml;r glRasterPos festlegen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   glRasterPos3f(-0.1,0,-1);  &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// (sichtbare) Rasterposition eintellen&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
   ShowText(&amp;lt;font color=&amp;quot;#FF2222&amp;quot;&amp;gt;'OpenGL '&amp;lt;/font&amp;gt;);&lt;br /&gt;
   ShowText(&amp;lt;font color=&amp;quot;#FF2222&amp;quot;&amp;gt;'Wiki'&amp;lt;/font&amp;gt;);          &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;&amp;lt;i&amp;gt;// Steht nach &amp;amp;quot;OpenGL&amp;amp;quot; da glBitmap die Rasterposition verschiebt.&amp;lt;/i&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end&amp;lt;/b&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[glBitmap]], [[glListBase]], [[glCallLists]], [[wglUseFontOutlines]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:WGL|UseFontBitmaps]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=12606</id>
		<title>glTexImage</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=12606"/>
				<updated>2005-09-30T07:19:09Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Fehlermeldungen */ Gibt keinen Parameter components&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glTexImage =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glTexImage''' - Einstellungen zum Texturen zeichnen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Spezifikation ==&lt;br /&gt;
 procedure '''glTexImage1D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage2D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; &lt;br /&gt;
                        '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage3D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''depth'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; &lt;br /&gt;
                        ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''target''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt an, welche Texture erreicht werden soll.  Muss je nach Funktionsaufruf '''GL_TEXTURE_1D,GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' sein.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''level''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt den Detailgrad für das gewünschte Bild an. &amp;lt;br&amp;gt;&lt;br /&gt;
''level'' '''0''' ist das Basisbild. Level n ist die n-te Mipmap reduzierung des Bildes.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''internalformat''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''1''' für '''R''' &amp;lt;br&amp;gt; '''2''' für '''R''' und '''A''' &amp;lt;br&amp;gt; '''3''' für '''RGB''' &amp;lt;br&amp;gt; '''4''' für '''RGBA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''width'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite = Anzahl der Pixel pro Zeile &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''height'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Höhe = Anzahl der Zeilen &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''depth'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Tiefe = Anzahl der &amp;quot;Scheiben&amp;quot; &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''border'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite des Rahmens || '''0''' oder '''1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''format''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt das Format der Pixeldaten. Folgende symbolische Werte werden akzeptiert: &amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,''' und '''GL_LUMINANCE_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''_type''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt den Pixeltyp für den Inhalt von ''pixels''. Folgende Typen werden unterstützt:&amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_BITMAP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''pixels''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Die Texture-Image Daten vom Typ, der in ''format'' angegeben wurde ( Array wo die Pixel gespeichert sind ) &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Texturierung bildet einen bestimmten Teil eines Texturbildes auf alle [[Primitive|Grafikprimitiven]] ab für die Texturierung aktiviert ist.&lt;br /&gt;
&lt;br /&gt;
Je nachdem welche Texturart aktiviert werden soll ruft man [[glEnable]] mit den Parametern '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' auf. Die Deaktivierung erfolgt entsprechend mittels [[glDisable]].&lt;br /&gt;
&lt;br /&gt;
Die Texturbilder werden durch die Funktionen '''glTexImage1D, glTexImage2D''' bzw. '''glTexImage3D''' definiert. Die Argumente der Funktionen beschreiben die Eigenschaften des Texturbildes wie z.B. Breite, Höhe, Tiefe (je nach Dimension), Breite des Randes, [[LOD]]-Nummer (siehe [[glTexParameter]]) und Anzahl der unterstützen Farbkomponenten. Die letzten 3 Argumente beschreiben wie das Bild im Speicher abgelegt wird. Die 3 Argumente sind identisch mit denen, die das Pixelformat bei [[glDrawPixels]] steuern.&lt;br /&gt;
&lt;br /&gt;
Die Daten werden aus ''pixels'' als Sequenz von vorzeichenlosen oder -behafteten Byte-, Shortint- oder Longint-Werten oder als Fließkommazahlen einfacher Genauigkeit gelesen. Der Typ wird über ''type'' festgelegt. &amp;lt;br&amp;gt;&lt;br /&gt;
Die ausgelesen Werte werden abhängig von ''format'' gruppiert zu Gruppen mit je einem, zwei, drei oder vier Werten. Diese Gruppen entsprechen einem Element. &lt;br /&gt;
&lt;br /&gt;
Wenn ''type'' gleich '''GL_BITMAP''' ist, werden die Daten als Folge (orig.: &amp;quot;String&amp;quot;) von vorzeichenlosen Bytewerten angesehen (wobei ''format'' '''GL_COLOR_INDEX''' sein muss). Jedes Byte des Datenblocks wird als Gruppe von 8 1-Bit Elementen interpretiert. Die Reihenfolge der Bits wird durch '''GL_UNPACK_LSB_FIRST''' (siehe [[glPixelStore]]) festgelegt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der ''format'' Parameter bestimmt die Zusammenstellung der Elemente aus ''pixels''. Folgende 9 möglichen Werte kann ''format'' haben:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GL_COLOR_INDEX'''&lt;br /&gt;
:Jedes Element entspricht einem einzelnen Wert, dem Farbindex. Jeder Index wird in eine Festkommazahl (mit einer unbestimmten Anzahl 0 Bits rechts vom Komma) konvertiert, abhängig von Wert und Vorzeichen von '''GL_INDEX_SHIFT''' bitweise nach rechts bzw. links verschoben und zu GL_INDEX_OFFSET addiert. Dann werden die Indizes durch ihre entsprechenden Werte aus den Tabellen '''GL_PIXEL_MAP_I_TO_R''', '''GL_PIXEL_MAP_I_TO_G''', '''GL_PIXEL_MAP_I_TO_B''' und '''GL_PIXEL_MAP_I_TO_A''' ersetzt und auf das Interval [0, 1] heruntergerechnet.&lt;br /&gt;
&lt;br /&gt;
'''GL_RED'''&lt;br /&gt;
:Jedes Element entspricht einer roten Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_GREEN'''&lt;br /&gt;
:Jedes Element entspricht einer grünen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_BLUE'''&lt;br /&gt;
:Jedes Element entspricht einer blauen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einer Alpha-Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die drei anderen Farben hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGB'''&lt;br /&gt;
:Jedes Element entspricht den drei RGB-Farbwerten. Die Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGBA'''&lt;br /&gt;
:Jedes Element enthält alle vier Farbkomponenten. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE'''&lt;br /&gt;
:Jedes Element entspricht einem Helligkeitswert. Der Wert wird in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einem Paar aus Helligkeitswert und Alphawert. Beide Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und den Alphawert hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lesen Sie den Artikel [[glDrawPixels]] um eine Beschreibung der zulässigen Werte für ''type'' zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Ein Texturbild kann bis zu 4 Farbkomponenten pro Texturelement ([[Texel]]) besitzen. Dies wird über den Parameter ''internalformat'' geregelt. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild welches nur eine Komponente besitzt, beenutzt nur die Rotwerte der aus ''pixels'' extrahierten RGBA Farbe. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit zwei Komponenten benutzt nur die Rot und Alpha Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit drei Komponenten benutzt nur die Rot, Grün und Blau Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit vier Komponenten benutzt alle RGBA Farbkomponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
'''glTexImage3D''' war bis zu OpenGL 1.2 nur eine Erweiterung. Deswegen ist bei manchen Chipsätzen die Funktion nur als '''glTexImage3DEXT''' verfügbar.&lt;br /&gt;
&lt;br /&gt;
Texturierung hat im Farbindexmodus keinen Effekt.&lt;br /&gt;
&lt;br /&gt;
Das Texturbild kann in den selben Datenformaten vorliegen wie die Pixel bei [[glDrawPixels]] ausgenommen '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT'''. [[glPixelStore]] und [[glPixelTransfer]] beeinflussen das Texturebil in exakt der Art und Weise, wie sie auch [[glDrawPixels]] beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Eine Textur die 0 Pixel hoch oder breit ist, stellt die NULL-Textur dar. Wenn die NULL-Textur für die LOD-Stufe 0 spezifiziert wird entspricht das Verhalten dem bei deaktivierter Texturierung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Änderungen ==&lt;br /&gt;
Folgende Erweiterungen hat die Funktion erfahren:&lt;br /&gt;
&lt;br /&gt;
=== Ab OpenGL Version 1.3 ===&lt;br /&gt;
[[GL_ARB_texture_cube_map]] definiert weitere 6 2D-Texture-Typen welche als ''target'' angegeben werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''target'' nicht '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' ist. (entsprechend der benutzten Funktion)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''format'' ungültige Werte übergeben wurden. Akzeptiert werden alle Formatangaben außer '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT''' &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''type'' keine gültige Typkonstante übergeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn GL_BITMAP als ''type'' und '''GL_COLOR_INDEX nicht(!)''' als ''format'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''level'' kleiner 0 oder größer ld(max) ist, wobei max der Rückgabewert von '''GL_MAX_TEXTURE_SIZE''' ist. (ld = Logarithmus Dualis = Basis 2). &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn für ''internalformat'' etwas anderes als ''1'', ''2'', ''3'' oder ''4'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''width'', ''height'' bzw. ''depth'' (je nach Funktion) kleiner als 0 oder größer als 2 + '''GL_MAX_TEXTURE_SIZE''' ist, oder die Bedingung  2^k + 2 * (border) (k=Integerwerte) nich erfüllt. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wenn ''border'' nicht ''0'' oder ''1'' ist. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn eine '''glTexImage'''-Funktion in einem [[glBegin]]- und [[glEnd]]-Block aufgerufen wird. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGetTexImage]] &amp;lt;br&amp;gt;&lt;br /&gt;
[[glIsEnabled]] mit dem Token '''GL_TEXTURE_1D''', '''GL_TEXTURE_2D''' bzw. '''GL_TEXTURE_2D'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glTexEnv]], [[glTexGen]], [[glTexSubImage1D]], [[glTexSubImage2D]], [[glTexSubImage3D]], [[glTexParameter]], [[glTexCoord]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|TexImage]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=9742</id>
		<title>glTexImage</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=9742"/>
				<updated>2005-09-30T07:13:41Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Beschreibung */ Es gibt keinen Parameter Components&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glTexImage =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glTexImage''' - Einstellungen zum Texturen zeichnen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Spezifikation ==&lt;br /&gt;
 procedure '''glTexImage1D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage2D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; &lt;br /&gt;
                        '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage3D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''depth'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; &lt;br /&gt;
                        ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''target''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt an, welche Texture erreicht werden soll.  Muss je nach Funktionsaufruf '''GL_TEXTURE_1D,GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' sein.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''level''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt den Detailgrad für das gewünschte Bild an. &amp;lt;br&amp;gt;&lt;br /&gt;
''level'' '''0''' ist das Basisbild. Level n ist die n-te Mipmap reduzierung des Bildes.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''internalformat''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''1''' für '''R''' &amp;lt;br&amp;gt; '''2''' für '''R''' und '''A''' &amp;lt;br&amp;gt; '''3''' für '''RGB''' &amp;lt;br&amp;gt; '''4''' für '''RGBA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''width'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite = Anzahl der Pixel pro Zeile &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''height'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Höhe = Anzahl der Zeilen &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''depth'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Tiefe = Anzahl der &amp;quot;Scheiben&amp;quot; &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''border'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite des Rahmens || '''0''' oder '''1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''format''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt das Format der Pixeldaten. Folgende symbolische Werte werden akzeptiert: &amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,''' und '''GL_LUMINANCE_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''_type''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt den Pixeltyp für den Inhalt von ''pixels''. Folgende Typen werden unterstützt:&amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_BITMAP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''pixels''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Die Texture-Image Daten vom Typ, der in ''format'' angegeben wurde ( Array wo die Pixel gespeichert sind ) &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Texturierung bildet einen bestimmten Teil eines Texturbildes auf alle [[Primitive|Grafikprimitiven]] ab für die Texturierung aktiviert ist.&lt;br /&gt;
&lt;br /&gt;
Je nachdem welche Texturart aktiviert werden soll ruft man [[glEnable]] mit den Parametern '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' auf. Die Deaktivierung erfolgt entsprechend mittels [[glDisable]].&lt;br /&gt;
&lt;br /&gt;
Die Texturbilder werden durch die Funktionen '''glTexImage1D, glTexImage2D''' bzw. '''glTexImage3D''' definiert. Die Argumente der Funktionen beschreiben die Eigenschaften des Texturbildes wie z.B. Breite, Höhe, Tiefe (je nach Dimension), Breite des Randes, [[LOD]]-Nummer (siehe [[glTexParameter]]) und Anzahl der unterstützen Farbkomponenten. Die letzten 3 Argumente beschreiben wie das Bild im Speicher abgelegt wird. Die 3 Argumente sind identisch mit denen, die das Pixelformat bei [[glDrawPixels]] steuern.&lt;br /&gt;
&lt;br /&gt;
Die Daten werden aus ''pixels'' als Sequenz von vorzeichenlosen oder -behafteten Byte-, Shortint- oder Longint-Werten oder als Fließkommazahlen einfacher Genauigkeit gelesen. Der Typ wird über ''type'' festgelegt. &amp;lt;br&amp;gt;&lt;br /&gt;
Die ausgelesen Werte werden abhängig von ''format'' gruppiert zu Gruppen mit je einem, zwei, drei oder vier Werten. Diese Gruppen entsprechen einem Element. &lt;br /&gt;
&lt;br /&gt;
Wenn ''type'' gleich '''GL_BITMAP''' ist, werden die Daten als Folge (orig.: &amp;quot;String&amp;quot;) von vorzeichenlosen Bytewerten angesehen (wobei ''format'' '''GL_COLOR_INDEX''' sein muss). Jedes Byte des Datenblocks wird als Gruppe von 8 1-Bit Elementen interpretiert. Die Reihenfolge der Bits wird durch '''GL_UNPACK_LSB_FIRST''' (siehe [[glPixelStore]]) festgelegt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der ''format'' Parameter bestimmt die Zusammenstellung der Elemente aus ''pixels''. Folgende 9 möglichen Werte kann ''format'' haben:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GL_COLOR_INDEX'''&lt;br /&gt;
:Jedes Element entspricht einem einzelnen Wert, dem Farbindex. Jeder Index wird in eine Festkommazahl (mit einer unbestimmten Anzahl 0 Bits rechts vom Komma) konvertiert, abhängig von Wert und Vorzeichen von '''GL_INDEX_SHIFT''' bitweise nach rechts bzw. links verschoben und zu GL_INDEX_OFFSET addiert. Dann werden die Indizes durch ihre entsprechenden Werte aus den Tabellen '''GL_PIXEL_MAP_I_TO_R''', '''GL_PIXEL_MAP_I_TO_G''', '''GL_PIXEL_MAP_I_TO_B''' und '''GL_PIXEL_MAP_I_TO_A''' ersetzt und auf das Interval [0, 1] heruntergerechnet.&lt;br /&gt;
&lt;br /&gt;
'''GL_RED'''&lt;br /&gt;
:Jedes Element entspricht einer roten Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_GREEN'''&lt;br /&gt;
:Jedes Element entspricht einer grünen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_BLUE'''&lt;br /&gt;
:Jedes Element entspricht einer blauen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einer Alpha-Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die drei anderen Farben hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGB'''&lt;br /&gt;
:Jedes Element entspricht den drei RGB-Farbwerten. Die Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGBA'''&lt;br /&gt;
:Jedes Element enthält alle vier Farbkomponenten. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE'''&lt;br /&gt;
:Jedes Element entspricht einem Helligkeitswert. Der Wert wird in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einem Paar aus Helligkeitswert und Alphawert. Beide Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und den Alphawert hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lesen Sie den Artikel [[glDrawPixels]] um eine Beschreibung der zulässigen Werte für ''type'' zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Ein Texturbild kann bis zu 4 Farbkomponenten pro Texturelement ([[Texel]]) besitzen. Dies wird über den Parameter ''internalformat'' geregelt. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild welches nur eine Komponente besitzt, beenutzt nur die Rotwerte der aus ''pixels'' extrahierten RGBA Farbe. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit zwei Komponenten benutzt nur die Rot und Alpha Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit drei Komponenten benutzt nur die Rot, Grün und Blau Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit vier Komponenten benutzt alle RGBA Farbkomponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
'''glTexImage3D''' war bis zu OpenGL 1.2 nur eine Erweiterung. Deswegen ist bei manchen Chipsätzen die Funktion nur als '''glTexImage3DEXT''' verfügbar.&lt;br /&gt;
&lt;br /&gt;
Texturierung hat im Farbindexmodus keinen Effekt.&lt;br /&gt;
&lt;br /&gt;
Das Texturbild kann in den selben Datenformaten vorliegen wie die Pixel bei [[glDrawPixels]] ausgenommen '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT'''. [[glPixelStore]] und [[glPixelTransfer]] beeinflussen das Texturebil in exakt der Art und Weise, wie sie auch [[glDrawPixels]] beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Eine Textur die 0 Pixel hoch oder breit ist, stellt die NULL-Textur dar. Wenn die NULL-Textur für die LOD-Stufe 0 spezifiziert wird entspricht das Verhalten dem bei deaktivierter Texturierung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Änderungen ==&lt;br /&gt;
Folgende Erweiterungen hat die Funktion erfahren:&lt;br /&gt;
&lt;br /&gt;
=== Ab OpenGL Version 1.3 ===&lt;br /&gt;
[[GL_ARB_texture_cube_map]] definiert weitere 6 2D-Texture-Typen welche als ''target'' angegeben werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''target'' nicht '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' ist. (entsprechend der benutzten Funktion)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''format'' ungültige Werte übergeben wurden. Akzeptiert werden alle Formatangaben außer '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT''' &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''type'' keine gültige Typkonstante übergeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn GL_BITMAP als ''type'' und '''GL_COLOR_INDEX nicht(!)''' als ''format'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''level'' kleiner 0 oder größer ld(max) ist, wobei max der Rückgabewert von '''GL_MAX_TEXTURE_SIZE''' ist. (ld = Logarithmus Dualis = Basis 2). &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn für ''components'' etwas anderes als ''1'', ''2'', ''3'' oder ''4'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''width'', ''height'' bzw. ''depth'' (je nach Funktion) kleiner als 0 oder größer als 2 + '''GL_MAX_TEXTURE_SIZE''' ist, oder die Bedingung  2^k + 2 * (border) (k=Integerwerte) nich erfüllt. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wenn ''border'' nicht ''0'' oder ''1'' ist. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn eine '''glTexImage'''-Funktion in einem [[glBegin]]- und [[glEnd]]-Block aufgerufen wird. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGetTexImage]] &amp;lt;br&amp;gt;&lt;br /&gt;
[[glIsEnabled]] mit dem Token '''GL_TEXTURE_1D''', '''GL_TEXTURE_2D''' bzw. '''GL_TEXTURE_2D'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glTexEnv]], [[glTexGen]], [[glTexSubImage1D]], [[glTexSubImage2D]], [[glTexSubImage3D]], [[glTexParameter]], [[glTexCoord]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|TexImage]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=9741</id>
		<title>glTexImage</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=9741"/>
				<updated>2005-09-30T07:04:44Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Parameter */  Es gibt keinen Parameter Components&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glTexImage =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glTexImage''' - Einstellungen zum Texturen zeichnen&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Spezifikation ==&lt;br /&gt;
 procedure '''glTexImage1D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage2D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; &lt;br /&gt;
                        '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage3D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''depth'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; &lt;br /&gt;
                        ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''target''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt an, welche Texture erreicht werden soll.  Muss je nach Funktionsaufruf '''GL_TEXTURE_1D,GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' sein.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''level''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt den Detailgrad für das gewünschte Bild an. &amp;lt;br&amp;gt;&lt;br /&gt;
''level'' '''0''' ist das Basisbild. Level n ist die n-te Mipmap reduzierung des Bildes.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''internalformat''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''1''' für '''R''' &amp;lt;br&amp;gt; '''2''' für '''R''' und '''A''' &amp;lt;br&amp;gt; '''3''' für '''RGB''' &amp;lt;br&amp;gt; '''4''' für '''RGBA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''width'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite = Anzahl der Pixel pro Zeile &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''height'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Höhe = Anzahl der Zeilen &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''depth'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Tiefe = Anzahl der &amp;quot;Scheiben&amp;quot; &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''border'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite des Rahmens || '''0''' oder '''1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''format''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt das Format der Pixeldaten. Folgende symbolische Werte werden akzeptiert: &amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,''' und '''GL_LUMINANCE_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''_type''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt den Pixeltyp für den Inhalt von ''pixels''. Folgende Typen werden unterstützt:&amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_BITMAP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''pixels''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Die Texture-Image Daten vom Typ, der in ''format'' angegeben wurde ( Array wo die Pixel gespeichert sind ) &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Texturierung bildet einen bestimmten Teil eines Texturbildes auf alle [[Primitive|Grafikprimitiven]] ab für die Texturierung aktiviert ist.&lt;br /&gt;
&lt;br /&gt;
Je nachdem welche Texturart aktiviert werden soll ruft man [[glEnable]] mit den Parametern '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' auf. Die Deaktivierung erfolgt entsprechend mittels [[glDisable]].&lt;br /&gt;
&lt;br /&gt;
Die Texturbilder werden durch die Funktionen '''glTexImage1D, glTexImage2D''' bzw. '''glTexImage3D''' definiert. Die Argumente der Funktionen beschreiben die Eigenschaften des Texturbildes wie z.B. Breite, Höhe, Tiefe (je nach Dimension), Breite des Randes, [[LOD]]-Nummer (siehe [[glTexParameter]]) und Anzahl der unterstützen Farbkomponenten. Die letzten 3 Argumente beschreiben wie das Bild im Speicher abgelegt wird. Die 3 Argumente sind identisch mit denen, die das Pixelformat bei [[glDrawPixels]] steuern.&lt;br /&gt;
&lt;br /&gt;
Die Daten werden aus ''pixels'' als Sequenz von vorzeichenlosen oder -behafteten Byte-, Shortint- oder Longint-Werten oder als Fließkommazahlen einfacher Genauigkeit gelesen. Der Typ wird über ''type'' festgelegt. &amp;lt;br&amp;gt;&lt;br /&gt;
Die ausgelesen Werte werden abhängig von ''format'' gruppiert zu Gruppen mit je einem, zwei, drei oder vier Werten. Diese Gruppen entsprechen einem Element. &lt;br /&gt;
&lt;br /&gt;
Wenn ''type'' gleich '''GL_BITMAP''' ist, werden die Daten als Folge (orig.: &amp;quot;String&amp;quot;) von vorzeichenlosen Bytewerten angesehen (wobei ''format'' '''GL_COLOR_INDEX''' sein muss). Jedes Byte des Datenblocks wird als Gruppe von 8 1-Bit Elementen interpretiert. Die Reihenfolge der Bits wird durch '''GL_UNPACK_LSB_FIRST''' (siehe [[glPixelStore]]) festgelegt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der ''format'' Parameter bestimmt die Zusammenstellung der Elemente aus ''pixels''. Folgende 9 möglichen Werte kann ''format'' haben:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GL_COLOR_INDEX'''&lt;br /&gt;
:Jedes Element entspricht einem einzelnen Wert, dem Farbindex. Jeder Index wird in eine Festkommazahl (mit einer unbestimmten Anzahl 0 Bits rechts vom Komma) konvertiert, abhängig von Wert und Vorzeichen von '''GL_INDEX_SHIFT''' bitweise nach rechts bzw. links verschoben und zu GL_INDEX_OFFSET addiert. Dann werden die Indizes durch ihre entsprechenden Werte aus den Tabellen '''GL_PIXEL_MAP_I_TO_R''', '''GL_PIXEL_MAP_I_TO_G''', '''GL_PIXEL_MAP_I_TO_B''' und '''GL_PIXEL_MAP_I_TO_A''' ersetzt und auf das Interval [0, 1] heruntergerechnet.&lt;br /&gt;
&lt;br /&gt;
'''GL_RED'''&lt;br /&gt;
:Jedes Element entspricht einer roten Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_GREEN'''&lt;br /&gt;
:Jedes Element entspricht einer grünen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_BLUE'''&lt;br /&gt;
:Jedes Element entspricht einer blauen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einer Alpha-Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die drei anderen Farben hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGB'''&lt;br /&gt;
:Jedes Element entspricht den drei RGB-Farbwerten. Die Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGBA'''&lt;br /&gt;
:Jedes Element enthält alle vier Farbkomponenten. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE'''&lt;br /&gt;
:Jedes Element entspricht einem Helligkeitswert. Der Wert wird in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einem Paar aus Helligkeitswert und Alphawert. Beide Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und den Alphawert hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''&amp;lt;i&amp;gt;c&amp;lt;/i&amp;gt;'''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lesen Sie den Artikel [[glDrawPixels]] um eine Beschreibung der zulässigen Werte für ''type'' zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Ein Texturbild kann bis zu 4 Farbkomponenten pro Texturelement ([[Texel]]) besitzen. Dies wird über den Parameter ''components'' geregelt. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild welches nur eine Komponente besitzt, beenutzt nur die Rotwerte der aus ''pixels'' extrahierten RGBA Farbe. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit zwei Komponenten benutzt nur die Rot und Alpha Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit drei Komponenten benutzt nur die Rot, Grün und Blau Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit vier Komponenten benutzt alle RGBA Farbkomponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
'''glTexImage3D''' war bis zu OpenGL 1.2 nur eine Erweiterung. Deswegen ist bei manchen Chipsätzen die Funktion nur als '''glTexImage3DEXT''' verfügbar.&lt;br /&gt;
&lt;br /&gt;
Texturierung hat im Farbindexmodus keinen Effekt.&lt;br /&gt;
&lt;br /&gt;
Das Texturbild kann in den selben Datenformaten vorliegen wie die Pixel bei [[glDrawPixels]] ausgenommen '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT'''. [[glPixelStore]] und [[glPixelTransfer]] beeinflussen das Texturebil in exakt der Art und Weise, wie sie auch [[glDrawPixels]] beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Eine Textur die 0 Pixel hoch oder breit ist, stellt die NULL-Textur dar. Wenn die NULL-Textur für die LOD-Stufe 0 spezifiziert wird entspricht das Verhalten dem bei deaktivierter Texturierung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Änderungen ==&lt;br /&gt;
Folgende Erweiterungen hat die Funktion erfahren:&lt;br /&gt;
&lt;br /&gt;
=== Ab OpenGL Version 1.3 ===&lt;br /&gt;
[[GL_ARB_texture_cube_map]] definiert weitere 6 2D-Texture-Typen welche als ''target'' angegeben werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''target'' nicht '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' ist. (entsprechend der benutzten Funktion)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''format'' ungültige Werte übergeben wurden. Akzeptiert werden alle Formatangaben außer '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT''' &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''type'' keine gültige Typkonstante übergeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn GL_BITMAP als ''type'' und '''GL_COLOR_INDEX nicht(!)''' als ''format'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''level'' kleiner 0 oder größer ld(max) ist, wobei max der Rückgabewert von '''GL_MAX_TEXTURE_SIZE''' ist. (ld = Logarithmus Dualis = Basis 2). &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn für ''components'' etwas anderes als ''1'', ''2'', ''3'' oder ''4'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''width'', ''height'' bzw. ''depth'' (je nach Funktion) kleiner als 0 oder größer als 2 + '''GL_MAX_TEXTURE_SIZE''' ist, oder die Bedingung  2^k + 2 * (border) (k=Integerwerte) nich erfüllt. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wenn ''border'' nicht ''0'' oder ''1'' ist. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn eine '''glTexImage'''-Funktion in einem [[glBegin]]- und [[glEnd]]-Block aufgerufen wird. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGetTexImage]] &amp;lt;br&amp;gt;&lt;br /&gt;
[[glIsEnabled]] mit dem Token '''GL_TEXTURE_1D''', '''GL_TEXTURE_2D''' bzw. '''GL_TEXTURE_2D'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glTexEnv]], [[glTexGen]], [[glTexSubImage1D]], [[glTexSubImage2D]], [[glTexSubImage3D]], [[glTexParameter]], [[glTexCoord]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|TexImage]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorial_Lektion_4&amp;diff=10876</id>
		<title>Tutorial Lektion 4</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorial_Lektion_4&amp;diff=10876"/>
				<updated>2005-09-29T13:43:27Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Tapeten besorgen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Texturen, Tapeten und Ihre Tücken=&lt;br /&gt;
&lt;br /&gt;
==Vorwort==&lt;br /&gt;
Hi Leute,&lt;br /&gt;
kaum zu glauben, aber wahr. Dieses Tutorial wird ausnahmsweise mal etwas mehr Erholung sein. Zumindest am Anfang. Was wir bisher erreicht haben ist ja alles schön, nett, praktisch und auch wichtig als Grundlage, aber wenn wir aus dem Fenster sehen, hören wir die Vöglein zwitschern. Hö? Wir hören was sehend? Es ist tiefste Nacht? Es muss Frühling sein ^__^.&amp;lt;br&amp;gt;&lt;br /&gt;
Und was macht man da Normalweise? Wir kramen herum und machen einen großen Frühjahrsputz die Schränke abziehen und alles schön sauber und ordentlich machen. Hach es dürstet mich richtig danach :D (means *würg*).&amp;lt;br&amp;gt;&lt;br /&gt;
Da unsere Tutorials bisher Gott sei Dank keine dreckige Sache waren, werden wir das mit dem Saubermachen einfach mal wegfallen lassen und uns nur mit einem Tapetenwechsel begnügen. In der Tat werden wir ab jetzt unseren Tutorials mehr grafisches Gewicht zumuten. Endlich haben die blauen Dreiecke ein Ende! Ich wünsche Euch viel Spaß ;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Crash-Kurs im Handwerk des Tapezierens==&lt;br /&gt;
&lt;br /&gt;
===Ich verstehe nur &amp;quot;Renovierung&amp;quot;?===&lt;br /&gt;
Ich finde es immer wieder erschreckend Leute im Internet zu treffen, die nicht wissen was eine Textur ist ich meine, kennen keinen Kafka, keine Quantenphysik und wissen nicht einmal wo man die Systemsteuerung findet. Wie soll man solch einem Menschen erklären, was eine Textur ist?&lt;br /&gt;
Nun, am Besten fangen wir mit einem möglichst praktischen Beispiel an. Texturen sind wie Tapeten. Wir blicken nun zu unserer linken Seite. Der Autor erwartet nun ein DirectMind-Uplink zum Empfangen der visuellen Bildsignale. Dort haben wir eine schöne Wand quadratisch in ihrer Form. Wollen wir diese mit einer Tapete verzieren, gehen wir in den nächsten Baumarkt, suchen uns eine hübsche aus und bringen diese an der Wand an. Natürlich haben wir eine große geholt, und fangen nicht mit kleinen Streifen an.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn dann alles geklappt hat stehen wir vor dieser Wand und begutachten die Tapete in voller Pracht direkt vor uns. Wir haben die Wand texturiert. Streng genommen machen wir auch bei OpenGL nichts anderes, als ein Bild zu laden und dieses auf eine Fläche zu kleben. Wir werden uns jedoch auf Dauer nicht damit begnügen immer nur quadratische Flächen zu texturieren, sondern durchaus auch mal Dreiecke oder andere Vielecke. Und auch hat man uns Werkzeuge in die Hand gegeben, um diese Textur noch nachträglich an der Wand zu verschieben, ohne dass wir sie abnehmen müssen. Ist doch super. Es lebe die virtuelle Welt!&lt;br /&gt;
&lt;br /&gt;
===Tapezieren leicht gemacht!===&lt;br /&gt;
Okay, wir haben lange genug um den heißen Brei herumgeredet und sollten uns nun endlich auf die Arbeit stürzen. Jeder von uns sollte in der Lage sein, ein Quadrat in OpenGL genau vor unserer Nase zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_nonetex.gif|thumb|256px|left|Leeres Quadrat]]&lt;br /&gt;
Spätestens nun sollte die gleiche Frage aufkommen, wie bei jedem, der zum ersten Mal versucht, eine Tapete an die Wand zu bringen: &amp;quot;Wie rum muss ich das Ding da befestigen?&amp;quot;. Immerhin müssen wir uns nicht um den Leim kümmern, das erledigt unsere Grafikkarte bzw. OpenGL für uns ;).&lt;br /&gt;
&lt;br /&gt;
Wer noch nie 3D programmiert hat, wird im ersten Moment vielleicht fälschlicherweise denken, dass man die Position der Textur per Weltkoordinaten definiert. Das hätte allerdings fatale Folgen, sobald sich das Objekt im Raum bewegt. Wir müssten die Position jedes mal neu berechnen. Um eben dieses Problem zu umgehen, geht man in der 3D-Programmierung einen anderen Weg. Man vergibt einfach für jede Ecke eines Objektes eine Koordinate der Textur. OpenGL errechnet dann aus diesen Texturkoordinaten das Stück der Textur, das dann über das gesamt Objekt projiziert wird.&lt;br /&gt;
&lt;br /&gt;
Die Rede ist hierbei vom so genannten UV-Mapping, welches vor allem bei Anfängern ein leichtes Gefühl des Unbehagens auslösen sollte. Es ist jedoch nur halb so wild, wenn man es halbwegs verstanden hat.&lt;br /&gt;
&lt;br /&gt;
Betrachten wir gleich mal folgendes Bild und versuchen, uns in die Problematik hineinzuversetzen. Da Texturen unterschiedliche Größen haben können wurden so genannte Texturkoordinaten eingeführt. Es ist total egal, wie groß eine Textur ist, da sie nur einen Wertebereich von 0 bis 1 haben kann. Das heißt, wenn eine Textur 256x256 groß ist und eine andere 512x512, so haben beide eine maximale Größe von 1. Wir brauchen also das UV-Mapping nicht verändern, selbst wenn ein Objekt eine neue Textur mit anderer Größe erhält!&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_texuv.gif|thumb|256px|right|Textur und leere Quadratfläche]]&lt;br /&gt;
Auf diesem Bild sehen wir zum einen die Textur, die wir verwenden wollen, zum anderen das Objekt, auf des &amp;quot;geklebt&amp;quot; werden soll. Natürlich sieht das in der Realität nicht so aus, ich denke aber diese Darstellung erleichtert das Verstehen ;).&lt;br /&gt;
&lt;br /&gt;
Der untere linke Bereich der Textur trägt die Texturkoordinaten von (0 / 0) (d.h. u = 0 und v = 0), der obere linke Bereich (0 / 1), der obere rechte Teil (1 / 1) und schließlich der untere rechte Bereich (1 / 0). Das heißt, alles was wir machen müssen, um auf unser Objekt eine Textur zu kleben, ist dem jeweiligen Eckpunkt unseres Quadrates die entsprechende Texturkoordinate zuzuweisen. Wobei in diesem Sinne korrekt in Anführungszeichnen stehen sollte. Es gibt kein falsches UV-Mapping! Man kann tolle Sachen mit diesen Textur-Koordinaten machen und so z.B. auch eine Textur auf einem Objekt spiegeln. Dafür müssten wir in unserem Beispiel nur die linken und rechten UV-Mapping vertauschen und z.B. für den zweiten Punkt die Koordinaten von (1 / 1) setzen und dafür beim dritten (0/ 1). Genauso würden wir auch die unteren vertauschen. Die UV-Koordinaten, wie sie oben angegeben sind, bedeuten nur, dass die Textur, so wie sie in der Datei vorkommt, auch auf das Objekt geklebt wird. Selbstverständlich ist es auch möglich eine Textur gekachelt aufkleben indem Ihr Texturkoordinaten &amp;gt; 1 vergebt, ebenso wie es möglich ist nur Teile einer Textur zu verwenden. Spielt ruhig ein wenig damit herum, und schaut Euch an was passiert! Auf einige tolle Spielerei kommen wir zum Schluss noch mal zurück :).&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_texuv_02.gif|thumb|256px|right|Textur und leere Quadratfläche]]&lt;br /&gt;
Sicherlich brennt es einigen von Euch nun bereits unter den Finger und Ihr fragt &amp;quot;wie kann ich denn die UV-Koordinaten den Eckpunkten der Fläche zuweisen?&amp;quot;. Nun, zunächst funktioniert das ähnlich wie bei allen Dingen unter OpenGL. Wir setzen eine UV-Koordinate und solange wir nichts verändern, werden alle Punkte mit diesen Koordinaten versehen, bis wir andere Instruktionen geben. In unserem Fall müssen wir dies natürlich nach jedem Punkt machen. Die Funktion, die dafür verwendet wird heißt glTexCoord. Um also eine Textur auf unserem Quad zu projizieren, benötigen wir folgenden Code:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;!-- Zeilen umbrüche sind drinnen damit das Bild nicht die Code-Boc verunstaltet --&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pascal&amp;gt;glBegin(GL_QUADS);&lt;br /&gt;
  glTexCoord2f(0,0); glVertex3f(-1,-1,0);&lt;br /&gt;
  glTexCoord2f(0,1); glVertex3f(-1,1,0);&lt;br /&gt;
  glTexCoord2f(1,1); glVertex3f(1,1,0);&lt;br /&gt;
  glTexCoord2f(1,0); glVertex3f(1,-1,0);&lt;br /&gt;
glEnd;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das klappt doch wunderbar oder? Damit wir die Textur aber auch wirklich genießen können müssen wir Texturing mit Hilfe von glEnable und dem Token GL_TEXTURE_2D aktivieren. Mit Hilfe von glDisable und demselben Token ist es dann auch möglich Objekte zu Zeichnen, die über keine Texturen verfügen. Andernfalls würde nämlich die zuletzt gesetzte Textur und die Texturkoordinaten des letzten glTexCoord-Aufrufs verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Doch eine Kleinigkeit habe ich Euch nun doch noch verschwiegen! Wir müssen natürlich noch die richtige Textur setzen, damit OpenGL überhaupt weiß, was auf diesem Quad gezeichnet werden soll. Dies ist an sich noch relativ einfach, allerdings müssen wir diese auch noch in den Speicher bekommen, damit sie überhaupt zur Verfügung steht. Nun wird's theoretisch ;).&lt;br /&gt;
&lt;br /&gt;
===Tapeten besorgen===&lt;br /&gt;
Ich werde jetzt nicht näher darauf eingehen, wie man Texturen erstellt, vielleicht gibt's ja einige Photoshop-Experten unter Euch, die Lust haben, einige Ihrer Tricks den anderen in Form eines Tutorials zu zeigen?&lt;br /&gt;
&lt;br /&gt;
Zunächst einmal müssen wir die uns die eigentlichen Bilddaten besorgen. Wir werden das jetzt in diesem Tutorial mit [[SDL]] machen es gibt jedoch auch die möglichkeit die Daten manuell zu laden das könnt ihr hier nachlesen:&lt;br /&gt;
* [[TGA Bilder laden]]&lt;br /&gt;
Es gibt allerdings auch Textur loader die euch die nächsten Kapitel abnehmen und das alles für euch machen. glBitmap ist so ein Loader, mehr dazu erfahrt ihr in dem [[Glbitmap_loader|glBitmap]]-Artikel.&lt;br /&gt;
&lt;br /&gt;
Bei SDL rufen wir nur [[IMG_Load]] auf und prüfen dann ob das Laden erfolgreich war. Hierbei sei erwähnt, dass es unter Linux zu Problemen führen kann, wenn ein Programm nicht aus einer Konsole heraus gestartet wurde. In diesem Fall sind die Pfade zu den Texturen nämlich falsch gesetzt und das Laden würde fehlschlagen. Abhilfe schafft man durch das Verwenden von absoluten Pfaden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;var &lt;br /&gt;
  tex : PSDL_Surface;&lt;br /&gt;
begin&lt;br /&gt;
  tex := IMG_Load(ExtractFileDir(paramStr(0))+'/wiki.jpg');&lt;br /&gt;
  if assigned(tex) then&lt;br /&gt;
  begin&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das war es dann auch schon wir haben die Textur im Speicher Doch was nun?&lt;br /&gt;
&lt;br /&gt;
===Texturen richtig zubereitet===&lt;br /&gt;
Nachdem sich unsere Textur nun im Speicher des Computers befindet, geht es darum, daraus auch eine richtige Textur zu machen, damit wir diese in OpenGL anzeigen können. Bisher befinden sich ja nur die Rohdaten im Speicher! Hierfür teilen wir OpenGL mit, dass wir eine neue Textur erzeugen wollen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;glGenTextures(1, TexID);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TexID ist in diesem Fall ein gluInt, kann aber genauso gut ein Array davon sein, um mehrere Texturen zu erzeugen. Genau dafür wird dann auch der erste Parameter verwendet, der OpenGL mitteilt, wie viele Texturen in dieses Array geschrieben werden sollen. In unserem Fall ist dies eben nur ein Element. Aber was ist ist das für ein Wert in TexID? OpenGL verwaltet die Texturen anhand eindeutiger Namen. glGenTextures ermittelt einen oder mehrere bisher ungenutzte Namen und schreibt diese in TexID. Durch TexId können wir unsere Textur ab sofort also eindeutig identifizieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;glBindTexture(GL_TEXTURE_2D, @TexID);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wir teilen OpenGL mit, dass sich von nun an alle Änderungen und Anweisungen, die sich auf Texturen beziehen auf die Textur TexID beziehen.&amp;lt;br&amp;gt;&lt;br /&gt;
Die folgenden beiden Zeilen sind zwar nicht wirklich nötig, um eine Textur zu erzeugen aber glaubt mir, sie werden ansonsten potthässlich aussehen. Wir werden in einem anderen Tutorial näher auf dessen Bedeutung eingehen, nämlich den so genannten Textur-Filtern. Die momentane Einstellung ist leicht rechenlastig, jedoch auch von recht guter Qualität. Ihr werdet anfangs keine Probleme mit der Geschwindigkeit bekommen ;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);&lt;br /&gt;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zu guter letzt werden müssen wir die Bildinformationen in unserem TBitmap-Objekt irgendwie OpenGL mitteilen. Dies übernimmt die Funktion glTexImage2D:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;glTexImage2D(GL_TEXTURE_2D, 0, 3, tex^.w, tex^.h,0, GL_RGB, GL_UNSIGNED_BYTE, tex^.pixels);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der erste Parameter steht für den Typ der Textur. Die Dimension des Typs muss hier mit der des Befehls übereinstimmen (glTexImage2D erlaubt also nur GL_TEXTURE_2D). Der zweite Parameter gibt die Nummer des Level of Detail (LoD) an. Für den Anfang reicht hier der Level 0. Der dritte Parameter gibt an, wie viele Farbkomponenten in dem Bild enthalten sind (1-4). Die zwei folgenden Parameter übermitteln OpenGL die Breite und die Höhe des Bildes. Der sechste Parameter gibt die Breite des Rahmens an. Im siebenten Parameter wird das Format verlangt, in welcher Reihenfolge die einzelnen Farbkomponenten gespeichert sind. Bei Bitmaps ist das immer die Reihenfolge Blau, Grün, Rot. Der Typ, der einzelnen Farbwerte muss im 8. Parameter angegeben werden. Letztendlich müssen im 9. Parameter nur noch die Bildpunkte selbst übergeben werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Mit Hilfe dieser Funktion sollten nur Texturen der Größe 2^n x 2^n erzeugt werden. Andernfalls werdet Ihr die Textur nicht in Ihrer vollen Schönheit, d.h. überhaupt nicht betrachten können. Es gibt jedoch Möglichkeiten Texturen zu laden, die nicht die Größe 2^n entsprechen. Die Funktion [[gluBuild2DMipmaps]] bildet hier beispielsweise eine Alternative.&amp;lt;br&amp;gt;&lt;br /&gt;
Das war es auch schon. Wer mehr über die einzelnen Parameter und Befehle wissen will ist herzlich eingeladen in unserem Wiki umherzustöbern und sein Wissen zu erweitern um später selbst vielleicht einmal ein paar Artikel im Wiki zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Die Daten im Arbeitsspeicher brauchen wir nun nicht mehr. Bei SDL geben wir sie so frei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;SDL_FreeSurface(tex);&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fassen wir das ganze bei SDL nochmal zusammen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;var&lt;br /&gt;
  tex : PSDL_Surface;&lt;br /&gt;
begin&lt;br /&gt;
  tex := IMG_Load('./wiki.jpg');&lt;br /&gt;
  if assigned(tex) then&lt;br /&gt;
  begin		&lt;br /&gt;
    glGenTextures(1, @texture);&lt;br /&gt;
    glBindTexture(GL_TEXTURE_2D, texture);&lt;br /&gt;
		&lt;br /&gt;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);&lt;br /&gt;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);&lt;br /&gt;
		&lt;br /&gt;
    // Achtung! Einige Bildformate erwarten statt GL_RGB, GL_BGR. Diese Konstante fehlt in den Standard-Headern&lt;br /&gt;
    glTexImage2D(GL_TEXTURE_2D, 0, 3, tex^.w, tex^.h,0, GL_RGB, GL_UNSIGNED_BYTE, tex^.pixels);&lt;br /&gt;
&lt;br /&gt;
    SDL_FreeSurface(tex);&lt;br /&gt;
  end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun kommt aber bitte nicht auf die Idee die Textur in euerer Hauptschleife wieder und wieder neu zu laden. Es reicht die Textur einmal zu laden und von da an steht sie einem solange zur Verfügung bis man gedenkt sie wieder aus dem Grafikkartenspeicher zu entfernen.&amp;lt;br&amp;gt;&lt;br /&gt;
Das übernimmt die Funktion [[glDeleteTextures]]. glDeleteTextures funktioniert ähnlich wie [[glGenTextures]], nur dass die Texturen entfernt werden. Der erste Parameter gibt die Anzahl der zu löschenden Texturen an, während der zweite Parameter den Namen der Textur bzw. ein Array der Namen mehrerer Texturen verlangt.&amp;lt;br&amp;gt;&lt;br /&gt;
Das ist doch für den Anfang nicht schlecht. Ihr solltet nun in der Lage sein, zumindest einfache Objekte zu texturieren. Das ist eigentlich das gesamte Grundprinzip. Natürlich gestaltet es sich schwieriger, ein komplexeres Objekt mit UV-Koordinaten zu versehen, als ein Quad, aber an der Technik selbst ändert sich nur wenig. Wir werden nun einige Spielereien zeigen, die man mit Texturen machen kann, damit Ihr ein Gefühl dafür bekommt, wie man ein Problem elegant umschiffen kann!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Die Rückkehr der Matrizen==&lt;br /&gt;
===Texturen===&lt;br /&gt;
Tja und da ich ein Sadist bin [Anm. des Lektors: Ooooh ja!] werden wir uns nun nochmals den Matrizen zuwenden! Dachtet Ihr etwa, Ihr seid die Dinger schon wieder los? Ich habe Euch im letzten Tutorial angedroht, dass es nicht nur eine Matrix für die &amp;quot;Welt&amp;quot; gibt, sondern auch noch weitere. Unter anderem eben auch für Texturen.&lt;br /&gt;
&lt;br /&gt;
Die Texturmatrix funktioniert streng genommen genauso wie auch die Worldmatrix. Solange wir sie aktiv haben, wird sie von jedem Matrixbefehl berücksichtigt! Einziger wirklicher Unterschied ist, dass sie nicht die Position oder die Form eines Objektes beeinflusst, sondern nur das Rendern der Textur selbst. Hö? Was meint der Kerl bloß damit?! Nun stellt Euch vor, Ihr habt ein Quad und wollt darauf eine Textur bewegen, so dass es aussieht, als würde sie sich von rechts nach links bewegen! Was wir jedoch nicht wollen ist, dass sich das Objekt bewegt, sondern nur, das was darauf zu sehen ist. Stellt Euch vor, Ihr schaut aus einem Fenster und seht einen wolkigen Himmel, der Wind bläst die Wolken von einer Himmelsrichtung zur anderen. Ihr könntet so z.B. das Fenster als Quad nehmen und dann die Textur darauf zeichnen und glaubt mir, die Illusion würde auffliegen, sobald sich das Fenster mit der Textur bewegen soll. Nein, stattdessen bewegen wir nur die Textur auf dem Quad und zwar ohne das UV-Mapping anzutasten. Wir beeinflussen einfach die Art, wie die Textur auf das Quad projiziert werden soll. Dafür dient die Texturmatrix.&lt;br /&gt;
&lt;br /&gt;
Stellen wir uns mal vor, dass wir unser Quad zeichnen und eine Variable X haben, die wir bei jedem Rendervorgang leicht erhöhen. Dies soll die Bewegung darstellen. Alles was wir nun tun müssen ist, die Texturmatrix entsprechend anzupassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
glMatrixMode(GL_TEXTURE);&lt;br /&gt;
  glLoadIdentity;&lt;br /&gt;
  glTranslatef(x,0,0);&lt;br /&gt;
glMatrixMode(GL_MODELVIEW);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist bereits der ganze Spuk! Wir teilen OpenGL durch glMatrixMode mit, dass sich ab sofort alle Veränderungen der Matrix nur noch auf die Texturmatrix beziehen sollen. Danach setzen wir diese sofort auf ihren Standardwert zurück. Der Grund hierfür sollte Euch von der Worldmatrix noch in Erinnerung sein. Anschließend ändern wir die Position der Textur auf dem Quad. Würden wir X jedes Mal um 1 Einheit erhöhen, so würde diese Operation ohne Effekt bleiben, da wir die Textur immer um ihre ganze Größe nach links projizieren würden. Würden wir X z.B. bei jedem Vorgang um 0.01 erhöhen, so würde die Textur sich langsam von rechts nach links bewegen. Ich denke, Ihr könnt bereits erahnen, welche Parameter dafür verwendet werden, um eine Textur von unten nach oben zu bewegen ;).&lt;br /&gt;
&lt;br /&gt;
Wichtig ist auf jeden Fall, dass Ihr anschließend mit glMatrixMode wieder die Worldmatrix aktiviert, da sonst alle weiteren Matrixmanipulationen auf die Texturmatrix angewandt werden würden. Denkt nicht, dass die Texturmatrix damit deaktiviert wird! Ab sofort wird auf das Objekt sowohl die World- als auch die Texturmatrix angewendet. Seht Ihr? Das Ganze ist doch gar nicht ganz so schlimm. Es versteht sich auch von selbst, dass Ihr glRotate und glScale ebenfalls darauf anwenden könnt, natürlich auch nach den gleichen Regeln auf die Worldmatrix. Experimentiert am Besten auch etwas mit diesen Einstellungen herum!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Wir tapezieren unsere Welt mal anders==&lt;br /&gt;
===Am Fließband===&lt;br /&gt;
Eigentlich sollte an dieser Stelle bereits Schluss sein. Ich wurde allerdings während des Schreibens des Tutorials nach einer Sache gefragt und möchte die Chance nutzen, diese Frage zu beantworten und gleichzeitig das angewandte Wissen der vorhergehenden Lektion etwas zu vertiefen. &lt;br /&gt;
&lt;br /&gt;
Wir haben folgende Problematik: Wir brauchen eine animierte Textur auf einem Objekt. Dies könnte z.B. eine bewegte Lavamasse sein oder irgendwas Glibbriges, was am Boden wabbelt. Oder eben in unserem Fall eine Folge von Zahlen, die wie ein Countdown aufgelistet werden. Sicherlich könnte nun jemand von Euch auf die Idee kommen, viele einzelne Texturen zu laden und diese in einem Array zu speichern. Dies mag auch durchaus sinnvoll sein nicht jedoch, wenn es sich um kleine Bilder handelt (bei uns z.B. 32x32 Pixel).&lt;br /&gt;
&lt;br /&gt;
Auch bei Bitmap-Fonts würde man nie auf die Idee kommen, für jeden Buchstaben eine einzelne Textur zu verwenden, sondern vielmehr eine Textur mit allen Buchstaben darauf erstellen, da dies u.a. den Ladevorgang erheblich beschleunigt! Klingt einleuchtend oder? Aber wie sollen wir dem Programm mitteilen, welcher Teil der Textur auf welche &amp;quot;Ecke&amp;quot; geklebt werden soll? Nun auch hierbei heißt des Lösungs Rätsel [Anm. des Lektors: Er macht's schon wieder. Herrlich] UV-Mapping!&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_numbers.gif]]&lt;br /&gt;
&lt;br /&gt;
Dies ist unsere Textur! Sie hat eine Gesamtlänge von 256x32 Bildpunkten und wie man leicht sehen kann, soll sie aus 8 Teilstücken bestehen. Die V-Koordinate können wir in diesem Fall getrost vernachlässigen, weil sie in diesem Fall immer konstant sein wird, weil wir die ganze Höhe der Textur verwenden wollen. Sie wäre nur dann interessant, wenn wir z.B. noch eine zweite Reihe darunter setzen würden. Ich denke jedoch, dass jemand der das gleich folgende verstanden hat, sofort eine Lösung für diese &amp;quot;Problematik&amp;quot; finden wird ;).&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_numbers2.gif]]&lt;br /&gt;
&lt;br /&gt;
Wichtig ist, dass wir uns bewusst werden, dass eine Textur beim UV-Mapping immer von 0 bis 1 reicht. Um nun die einzelnen Bilder aus einer Textur auf ein Objekt zu setzen, müssen wir nichts anderes machen, als zu errechnen, an welcher Stelle ein Bild anfängt und wo es aufhört. Nur zur Kontrolle, damit es auch jeder begreift: Würden wir nur die erste Hälfte der Textur auf ein Objekt kleben, so müsste unsere U-Koordinate von 0 bis 0.5 reichen. Die zweite Hälfte hingegen von 0.5 - 1.0. Soweit klingt es doch noch alles logisch oder?&lt;br /&gt;
&lt;br /&gt;
Genauso müssen wir auch vorgehen, wenn wir einzelne Bilder auf einem Quad abbilden wollen. In unserem Fall müsste die U-Koordinate von 0 bis 1/8 reichen. Das zweite Bildchen hingegen von 1/8 bis 2/8 etc. D.h. wir wissen, dass jedes unserer Bilder 1/8 &amp;quot;Einheiten&amp;quot; lang ist! Und somit haben wir ja bereits eine Lösung für unser Problem. Um das ganze dynamisch auszudrücken: Wir brauchen nur die Größe der Textur durch die Anzahl der Bilder zu teilen. Bevor jemand einen Denkfehler macht: Es ist hierbei ganz egal, wie groß die Textur wirklich ist (hier 256x32 Pixel). Dank OpenGL errechnen wir das UV-Mapping ja in absoluten Größen.&lt;br /&gt;
Nun der Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
PicLength:= 1 / PicCount;&lt;br /&gt;
PicPos:=Round(Pic)*PicLength;&lt;br /&gt;
glBegin(GL_QUADS);&lt;br /&gt;
  glTexCoord2f(PicPos,		    1); glVertex3f(-1,1,0);&lt;br /&gt;
  glTexCoord2f(PicPos + PicLength, 1); glVertex3f(1,1,0);&lt;br /&gt;
  glTexCoord2f(PicPos + PicLength, 0); glVertex3f(1,-1,0);&lt;br /&gt;
  glTexCoord2f(PicPos,		    0); glVertex3f(-1,-1,0);&lt;br /&gt;
glEnd;&lt;br /&gt;
&lt;br /&gt;
Pic:=Pic + MovementValue;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pic ist in diesem Fall eine Variable vom Typ Single, die langsam erhöht wird. Wir runden den Wert hier, so dass beim Erreichen eines jeden ganzzahligen Wertes das nächste Bild angezeigt wird. Wir multiplizieren die Nummer des anzuzeigenden Bildes mit der Breite eines Bildes, um die Anfangsposition zu erhalten und addieren dann noch eine volle Bildbreite dazu, um die Endposition zu erhalten. Hört sich gewaltig gefährlich an, liegt aber mehr an meinem mangelnden Ausdruck als an der Schwierigkeit dieses Problems ;).&lt;br /&gt;
&lt;br /&gt;
Im Sample werdet Ihr noch sehen, was passiert, wenn man den Wert nicht rundet. Man erhält in diesem Fall einen &amp;quot;flüssigen&amp;quot; Bildübergang. Letztendlich gibt es viele Möglichkeiten, solche Ideen zu implementieren. Nehmt dies einfach als kleineren Gedankenschub und vor allem: Werdet Euch bewusst, was genau dort passiert! Eine Menge toller Dinge lassen sich mit einem guten UV-Mapping erzielen.&lt;br /&gt;
Wer noch etwas umherexperimentieren will kann gern versuchen selbes Ziel mit Hilfe der Texturenmatrix zu erreichen. Die Lösung ist verblüffend einfach.&lt;br /&gt;
&lt;br /&gt;
===Terraforming mal anders===&lt;br /&gt;
Relativ lange habe ich nach einem guten Beispiel für folgende Problematik gesucht: Ich wollte Euch die UV-Koordinaten etwas näher bringen und Euch zeigen, wofür man sie einsetzen kann. Irgendwie wollte mir nichts Interessantes aus meinem Kopf entspringen bis ich irgendwann in einigen alten Programmen von mir rumgewühlt habe und einen alten Terrainrenderer von mir fand. Schon war die Idee da! Wir schreiben ein kleines Programm, das eine ganz simple, unoptimierte Landschaft rendern wird. Das hört sich sicherlich Anfangs relativ gewaltig an, mit etwas Verständnis für die oberen Probleme sollte dies jedoch kein Problem für Euch sein.&lt;br /&gt;
&lt;br /&gt;
Zuvor allerdings ein paar Gedankenspiele. Zunächst widmen wir uns kurz der Texturiering. Wie würde die simpelste Landschaft aussehen, die wir uns vorstellen können? Richtig! Sie wäre ein einfaches, flach liegendes Quadrat mit einer Textur überzogen, der Wand aus unserem ersten Versuch sehr ähnlich! Dies hat jedoch einen klitzekleinen Nachteil: Wir könnten keine Höhenstufen einbauen und ohne die wäre die Landschaft nur halb so realistisch. Denn wir wollen versuchen, folgende Szene zu zaubern:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_landscape.gif|thumb|256px|none|eine Lanschaft]]&lt;br /&gt;
Um allerdings Höhen einzubinden, müssen wir die Landschaft in viele kleinen Quads unterteilen, die natürlich an Ihren Eckpunkten unterschiedliche Höhen haben, sich jedoch jeweils einige Punkte teilen. Es versteht sich von selbst, dass diese die gleiche Höhe haben müssen, damit die Landschaft auch durchgängig ist und nicht irgendwelche mysteriösen Löcher darauf erscheinen ;).&lt;br /&gt;
Auf folgendem Screenshot kann man dies deutlich erkennen:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_landwire.gif|thumb|256px|left|Gitter Ansicht der Landschaft]]&lt;br /&gt;
Technisch gesehen ist das Ganze einfach zu realisieren, da wir nur begreifen müssen, dass alle Quads nebeneinander liegen und sich - bis auf die äußeren alle einen Eckpunkt teilen. Nun müssen wir beim Rendern jeden Eckpunkt nur noch vom angrenzenden Quad lesen und fertig ist die Landschaft. Ich will da nicht näher drauf eingehen, weil es sich hier nicht um ein Tutorial zur Landschaftsgestaltung handelt. Der Code sollte sich eigentlich von selbst erklären.&lt;br /&gt;
&lt;br /&gt;
Vielmehr sollten wir uns einer anderen Problematik widmen! Nämlich wie zur Hölle texturieren wir die Landschaft so, dass sie nicht zur Marke &amp;quot;augenfeindlich&amp;quot; gehört?&lt;br /&gt;
&lt;br /&gt;
[[Bild:Tutimg_lektion4_landscapeerror.gif|thumb|256px|right|wiederkehrende Landschaft]]&lt;br /&gt;
Wenn Euer erster Gedanke dabei &amp;quot;Boah, cool!&amp;quot; ist, dann gibt's eins auf die Finger! Das wollen wir doch nicht wie sieht den die Landschaft aus. Eine immer wiederkehrende Landschaft -&amp;gt; man erkennt sofort, dass wir hierbei auf jedes Quad die gleiche Textur geklebt haben. Doch wie schaffen wir es nun, dass wir eine Textur über alle Quads ziehen, so dass die ganze Landschaft mit einer Textur überzogen ist anstatt nur über ein einzelnes Feld?&lt;br /&gt;
Nun, des Lösungs Geheimnis [Anm. des Lektors: Ich liebe ihn dafür! Andere lösen Rätsel. Er geheimnist Lösungen] sind eben unsere UV-Koordinaten und einige pfiffige Köpfe unter Euch sollten bereits einen ersten Verdacht haben. Denn die erste Idee sollte es sein, den linken unteren Punkt eine UV-Koordinate von (0/0) zu geben und der rechten oberen (1/1).&lt;br /&gt;
Alles was wir nun also machen müssen, ist, uns die entsprechenden UV-Koordinaten für die Quads dazwischen auszurechnen und sie dann den Punkten zuzuweisen. Dafür benötigen wir zunächst die Breite eines Quads. Mit normaler Logik lässt sich folgende Aussage aufstellen.&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
qw:=1 / XCount&lt;br /&gt;
qh:=1 / YCount;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Ein Quad benötigt die Länge von 1 durch die Anzahl der Quads in einer Reihe oder Spalte. Genauso verhält es sich auch mit der Höhe. Nun brauchen wir beim Rendern nur noch dem jeweiligen Quad in einer For-Schleife die entsprechende Koordinate zuzuweisen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
U:=1 / XCount;&lt;br /&gt;
V:=1 / YCount;&lt;br /&gt;
&lt;br /&gt;
for y:=0 to YCount-1 do&lt;br /&gt;
begin&lt;br /&gt;
  glPushMatrix;&lt;br /&gt;
  for x:=0 to XCount-1 do&lt;br /&gt;
  begin&lt;br /&gt;
    glBegin(GL_QUADS);&lt;br /&gt;
      glTexCoord2f(U*x,     V*(y+1)); &lt;br /&gt;
      glVertex3f(0,  Map[x,y+1],  0);&lt;br /&gt;
      glTexCoord2f(U*x,     V*y);     &lt;br /&gt;
      glVertex3f(0,  Map[x,y],  1);&lt;br /&gt;
      glTexCoord2f(U*(x+1), V*y);     &lt;br /&gt;
      glVertex3f(1,  Map[x+1,y],  1);&lt;br /&gt;
      glTexCoord2f(U*(x+1), V*(y+1));  &lt;br /&gt;
      glVertex3f(1, Map[x+1,y+1],  0);&lt;br /&gt;
    glEnd;&lt;br /&gt;
    glTranslatef(1,0,0);&lt;br /&gt;
  end;&lt;br /&gt;
  glPopMatrix;&lt;br /&gt;
  glTranslatef(0,0,-1);&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Das sieht nach einem herben Stück Arbeit aus oder? Aber wenn Ihr Euch das ganze mal aufzeichnet und im Kopf durchspielt, wird der Groschen fallen. Denkt mal etwas darüber nach! Wenn es dann doch noch Probleme mit dem Verständnis geben sollte, wird das nächste Kapitel hoffentlich jedes Missverständnis aus dem Wege räumen ;).&lt;br /&gt;
&lt;br /&gt;
==Nachwort==&lt;br /&gt;
Okay ich hoffe Ihr fühlt Euch nach der Abarbeitung dieses Tutorials genauso wie ich, nachdem ich es für Euch geschrieben habe nämlich elend. Irgendwie wurde das immer mehr und ich sagte mir immer wieder &amp;quot;nein, dass ist nicht genug. Das muss genauer und anschaulicher werden&amp;quot;. Dies ist auch der Grund dafür, warum dieses eines der größten Tutorials mit den meisten Bildern usw geworden ist. Erst sollte es noch etwas mehr werden und dann in mehrere Tutorials aufgespaltet werden, allerdings glaube ich mit diesem Tutorial einen guten Mittelweg zwischen Information und Totlabern gefunden zu haben. Lasst es mich wissen, wie Ihr dazu steht!&amp;lt;br&amp;gt;&lt;br /&gt;
Und bevor die Kritiker gleich wieder alle aus Ihren Löchern kommen und mir sagen, dass einige Bereich einfach als gegeben angenommen werden; denen sei nur gesagt, dass wir u.a. auch versuchen Rücksicht auf Leute zu nehmen, die noch nie 3D programmiert haben und vielleicht Eurem Wissen nicht standhalten können. Daher halte ich es hier für wichtiger, Grundlagen wie UV-Koordinaten und den Einsatz von Texturen zu erklären, als ihnen tausende von Zeilen um die Ohren zu hauen, wie sie die Bytes von der Festplatte in den Arbeitsspeicher laden können. Um jedoch keine Wissenslöcher offen zu lassen: Ihr könnt Euch sicher sein, dass spezielle Tutorials folgen werden, die sich speziell mit dem Laden verschiedener Formate beschäftigen und die genaue Interna (was im Hintergrund abläuft) zu erklären versuchen. Auch das Alpha Blending wird hier mehr zu &amp;quot;Show-Zwecken&amp;quot; verwendet und wird zusammen mit dem Z-Buffer genauer erklärt werden! &amp;lt;br&amp;gt;&lt;br /&gt;
Also bloß keine falsche Hektik! Ich weiß ... einige von Euch sind recht ungeduldig, aber ständiges Nachfragen und Drängeln führt zu nichts. Versucht Fragen lieber ins Forum zu setzen, damit dort ein wenig Leben reinkommt. Denn wenn es dort belebter wird, kommen auch schneller neue Leute und vielleicht sind ja auch welche dabei, die dann das DGL-Team entlasten können. Also nutzt bitte das Forum, anstatt andauernd per ICQ oder Mail irgendwelche Fragen zu stellen! Die Antwort wird auch nicht viel länger auf sich warten lassen. Im Forum jedoch ist alles dokumentiert und auch anderen zugänglich, so dass ich nicht die gleiche Frage bis zu 5 mal am Tag beantworten muss. Sorry aber das geht einem auf die Nerven und vor allem auf die Zeit ;). Schließlich sind wir keine Maschinen sondern Menschen, die auch ein privates Leben haben ^__-.&lt;br /&gt;
&lt;br /&gt;
Glaubt uns, wir investieren einen sehr großen Teil unserer Zeit in dieses Projekt und solch ein Tutorial lässt sich nicht binnen weniger Tage anfertigen. Jeder der so etwas bereits einmal gemacht hat, wird wissen was ich meine. Es muss ein Konzept her, es müssen Samples geschrieben, Screenshots gemacht werden und ein halbwegs verständlicher Text her. Und nichtsdestotrotz soll es am Ende auch noch passen, einem möglichst großen Publikum Wissen vermitteln, am Besten von Schreib- und Sprachfehlern befreit und in einem halbwegs ansehnlichen HTML-Dokument präsentiert werden. Ein langer Weg ;).&lt;br /&gt;
Okay, in diesem Sinne, bis bald ;)!&lt;br /&gt;
btw: Vielen Dank an Magellan für die Bereitstellung und Integration seiner besonderen Lernleistung.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Euer&amp;lt;br&amp;gt;&lt;br /&gt;
'''Phobeus'''&lt;br /&gt;
&lt;br /&gt;
{{TUTORIAL_NAVIGATION|[[Tutorial_lektion3]]|[[Tutorial_lektion5]]}}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorial|Lektion4]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=9528</id>
		<title>Text ausgeben</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=9528"/>
				<updated>2005-09-12T10:13:56Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Farbe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Anleitung'''- Wie gebe ich mit OpenGL Text aus.=&lt;br /&gt;
&lt;br /&gt;
Allen Möglichkeiten gemein ist das die Buchstaben in [[Liste]]n gespeichert werden um so per [[glCallLists]] den Text ausgeben zu können.&lt;br /&gt;
&lt;br /&gt;
== Buchstaben aus Pixeln ==&lt;br /&gt;
&lt;br /&gt;
Die primitivste Art Buchtaben auszugeben besteht darin einfach [[glBitmap]] aufzurufen. &lt;br /&gt;
&lt;br /&gt;
Falls das Betriebssystem Windows ist, kann mit [[wglUseFontBitmaps]] aus einer Windows Schrift [[glBitmap]] Befehle generiert, und in einer [[Liste]] abgespeichert werden.&lt;br /&gt;
&lt;br /&gt;
=== Position festlegen ===&lt;br /&gt;
Die Position der Ausgabe erfolgt durch [[glRasterPos]], oder besser falls verfügbar durch [[glWindowPos]].&lt;br /&gt;
&lt;br /&gt;
=== Farbe ===&lt;br /&gt;
Die [[Farbe]] der Schrift wird zum Zeitpunkt des letzen [[glColor]] Aufrufes festgelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 3D Schriften mit Windows ==&lt;br /&gt;
&lt;br /&gt;
Per [[wglUseFontOutlines]] wird aus einer Windows Schrift für jeden Buchstaben eine Liste erstellt, welche die entsprechenden Polygone enthält.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|+Das kann dann so aussehen:&lt;br /&gt;
|[[Bild:WglUseFontOutlines Beispiel.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schrift aus Texturen ==&lt;br /&gt;
(Sogenannte Bitmapfonts)&lt;br /&gt;
&lt;br /&gt;
Benötigt wird für diese Technik eine Textur, auf dem alle 256 Zeichen untergebracht sind. Die Anordnung der Zeichen ist prinzipiell beliebig, nur sollte man dies so tun, dass man nachher leicht die Position der einzelnen Zeichen auf der Textur herausfindet. (z.B. indem man die Zeichen als 16x16 Zeichen Matrix anordnet). &lt;br /&gt;
&lt;br /&gt;
Zusätzliche Informationen über die Breite der Buchstaben, ermöglicht es gleich große Zwischenräume zwischen den einzenen Buchstaben zu haben.&lt;br /&gt;
Entsprechende [[Tool]]s erleichtern die Erstellung solcher Texturen.&lt;br /&gt;
&lt;br /&gt;
Die Textur [[Matrix]] wird dann mit  [[glScale]] und [[glTranslate]] so manipuliert, dass das mit [[glBegin]], [[glTexCoord]] und [[glVertex]] gezeichnete Rechteck immer nur ein Zeichen enthält. &lt;br /&gt;
('''glScale''' ist eigentlich nicht nötig, da ein mit [[glTexCoord]] abgesteckter Texturabschnitt automatisch auf die Größe des unterligenden Polygons (gezeichnet mit [[glBegin]]-[[glEnd]] und [[glVertex]]) gedehnt wird.)&lt;br /&gt;
&lt;br /&gt;
Um nur die Buchstaben ohne den Hintergrund (der Textur) zu sehen sollte dieser mittels [[Blenden|Blending]] oder (wenn man scharfe Kanten möchte) mittels [[glAlphaFunc]] heraus gefiltert werden.&lt;br /&gt;
&lt;br /&gt;
=== Position ===&lt;br /&gt;
Das '''Wo''' wird über die Koordinaten der [[Eckpunkt|Eckpunkte]] des unterliegenden Polygons geregelt. Welches Zeichen tatsächlich ausgegeben wird, bestimmen die Texturkoordinaten (übergeben mit [[glTexCoord]]).&lt;br /&gt;
&lt;br /&gt;
=== Farbe ===&lt;br /&gt;
Wenn man eine einfarbige Schrift möchte, so empfiehlt es sich die Textur komplett Weiß zu machen, damit man mit [[glColor]] die Textur einfärben kann und damit alle Farben anzeigen lassen kann. Dies kann beispielsweise auch mittels&lt;br /&gt;
 [[glPixelTransfer]]f( GL_RED_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_GREEN_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_BLUE_BIAS, 1.0 );&lt;br /&gt;
vor dem Erstellen der Textur erfolgen.&lt;br /&gt;
Der eigentliche Zeichensatz sollte (sofern man einfarbige Schrift möchte) nur den Alpha-Kanal beeinflussen, was beispielsweise mittels&lt;br /&gt;
 [[gluBuild2DMipmaps]]( GL_TEXTURE_2D, 2, Texturbreite, Texturhoehe, GL_ALPHA, GL_UNSIGNED_BYTE, Pixel );&lt;br /&gt;
gemacht werden kann. Zu beachten ist hier, dass 2 oder 4 Farbkomponenten benötigt werden damit die Textur Alphawerte erhält.&lt;br /&gt;
&lt;br /&gt;
Falls der Text nicht im 3 dimensionalen Raum angezeigt werden soll, empfiehlt es sich den [[Tiefentest]] zu deaktivieren und die Projektions Matrix mit [[gluOrtho2D]] neu einzustellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
[[glBegin]], [[glColor]], [[glScale]], [[glTranslate]], [[glTexCoord]], [[glVertex]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Diskussion:Low/High-Level&amp;diff=7912</id>
		<title>Diskussion:Low/High-Level</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Diskussion:Low/High-Level&amp;diff=7912"/>
				<updated>2005-07-07T14:40:46Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ich finde die Beispiele ein wenig unpassend. Laut der Definition wäre der Code für Highlevel eher für Lowlevel. Wobei ich persönlich beide Codes nach Highlevel einordnen würde, da beide Methoden nun mal Klassen benutzen. Bei dem &amp;quot;Highlevel&amp;quot; Beispiel befinden sich nur alle Parameter im Konstruktor und bei Lowlevel hat man sich sogar die Mühe gemacht properties dafür zu implementieren!?&lt;br /&gt;
&lt;br /&gt;
Oder um es mal an einem Beispiel anzubringen. Im Vergleich glBitmap.pas und die Textures.pas. Die Textures ist eindeutig Lowlevel. Eine Methode zum Laden von Texturen. Die glBitmap ist dort eindeutig Highlevel. Die Textures mag an einigen Stellen schneller sein, dafür '''fehlt''' ihr aber Flexibilität. Speiziell beim Laden und der Handhabung der Texturen. Sie kann nur das was wofür sie geschrieben wurden. Datei rein und TExturid raus. Änderungen können recht leicht nachgepflegt werden. Das ist bei der glBitmap nicht ganz so einfach. Da muss man schon aufpassen, dass es in das System passt. Ich finde Lowlevel ist eher unflexibel, da es nur auf bestimmte Aufgabengebiete zugeschnitten wird wärend Highlevel nun mal viele Verwendungszwecke zur Verfügung stellt. Highlevel geht eher abstrakt an die Aufgaben herran.&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=8867</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=8867"/>
				<updated>2005-07-05T11:39:09Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNGs laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7896</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7896"/>
				<updated>2005-07-05T11:35:09Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* glBitmap - Texturenloader */ 's durch s ersetzt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNGs laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7893</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7893"/>
				<updated>2005-07-05T09:27:54Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Texturen konfigurieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;nm4Samples&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;nmSobel&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Mit dieser Methode werden fließen benachbarten Pixel zu gleichen Teilen in die Berechnung ein.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;nm3x3&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;nm5x5&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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 BMP's 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7890</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7890"/>
				<updated>2005-07-05T08:54:49Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Normalmaps Procedural */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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 BMP's 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7887</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7887"/>
				<updated>2005-07-04T14:26:48Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Normalmaps mit glBitmap */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== 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 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 bei dem Hinzufügen des Alphakanals oder immer wenn man möchte durch die Methode &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmaps erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 LoadTexture(32, Texture);&lt;br /&gt;
&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 fNormalMap.GenerateNormalMap(32); &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Normalmap erzeugen&amp;lt;/font&amp;gt;&amp;lt;/i&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7886</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7886"/>
				<updated>2005-07-04T14:03:37Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== 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 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 bei dem Hinzufügen des Alphakanals oder immer wenn man möchte durch die Methode &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7885</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7885"/>
				<updated>2005-07-04T14:02:26Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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) 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== 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 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 bei dem Hinzufügen des Alphakanals oder immer wenn man möchte durch die Methode &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt;. Es gibt außerdem noch eine Reihe von Funktionen, die intern die Schnittstelle benutzen. Das wären zum Beispiel die Funktionen &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;AddAlphaFromColokey&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;FillWithColor&amp;lt;/i&amp;gt;. Die Klasse &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;. Zu erst einmal der Aufruf der Funktion.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; ((UseRGB) &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; (UseAlpha)) &lt;br /&gt;
   &amp;lt;b&amp;gt;then&amp;lt;/b&amp;gt; AddFunc(glBitmapInvertFunc, False, Pointer(Integer(UseAlpha &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; HasAlpha) &amp;lt;b&amp;gt;shl&amp;lt;/b&amp;gt; 1 &amp;lt;b&amp;gt;or&amp;lt;/b&amp;gt; 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 &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; auf. Diese Methode bekommt als erstes unsere Funktion übergeben. Zu deren Aufbau komme ich gleich. Als Zweites bekommt &amp;lt;i&amp;gt;AddFunc&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; glBitmapInvertFunc(Sender : TglBitmap; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Position, Size: TglBitmapPixelPosition; &lt;br /&gt;
   &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Source, Dest: TglBitmapPixelData; &amp;lt;b&amp;gt;const&amp;lt;/b&amp;gt; Data: Pointer);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $1 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptRed^   := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptRed^;&lt;br /&gt;
     Dest.ptGreen^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptGreen^;&lt;br /&gt;
     Dest.ptBlue^  := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptBlue^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   &amp;lt;b&amp;gt;if&amp;lt;/b&amp;gt; (Integer(Data) &amp;lt;b&amp;gt;and&amp;lt;/b&amp;gt; $2 &amp;gt; 0) &amp;lt;b&amp;gt;then begin&amp;lt;/b&amp;gt;&lt;br /&gt;
     Dest.ptAlpha^ := &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; Dest.ptAlpha^;&lt;br /&gt;
   &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Position&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Size&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; beinhalten die Pixeldaten. Die Records sind ziemlich genau so aufgebaut wie das für die Position. Es gibt einen Wert &amp;lt;i&amp;gt;Fields&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt;, da es ja die Möglichkeit gibt eine Kopie des Bildes zu erstellen. Sollte ohne Kopie gearbeitet werden so sind &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; gleich. Bei hinzufügen eines Alphakanals bezieht sich &amp;lt;i&amp;gt;Source&amp;lt;/i&amp;gt; auf die Pixeldaten im dem Quellbild und &amp;lt;i&amp;gt;Dest&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;ToNormalMap&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;TglBitmapNormalMap&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7884</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7884"/>
				<updated>2005-06-22T07:53:31Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Das leidige Thema Alphakanal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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) 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7789</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7789"/>
				<updated>2005-06-22T07:52:23Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Das leidige Thema Alphakanal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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) 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;RemoveAlpha&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt;. 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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// entfernt den Alphakanal&amp;lt;/font&amp;gt;&amp;lt;/i&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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7788</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7788"/>
				<updated>2005-06-22T07:35:41Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Texturen konfigurieren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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) 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FlipHorz&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Invert&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7787</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7787"/>
				<updated>2005-06-22T07:14:59Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Allgemeines und Features */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; 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) 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;
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;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Texture_Loader&amp;diff=9616</id>
		<title>Texture Loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Texture_Loader&amp;diff=9616"/>
				<updated>2005-06-22T07:08:57Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Bestehende Texture Loader */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Texture Loader=&lt;br /&gt;
&lt;br /&gt;
==Was ist das?==&lt;br /&gt;
Der '''Texture Loader''' ist ein Tool, welches das Verwalten von Texturen erleichtern soll.&amp;lt;br&amp;gt;&lt;br /&gt;
Sobald man Texturen in seinen Projekten verwenden will, benötigt man einen '''Texture Loader'''.&lt;br /&gt;
&lt;br /&gt;
==Was macht ein Texture Loader?==&lt;br /&gt;
Er lädt Texturen!&amp;lt;br&amp;gt;&lt;br /&gt;
So einfach wie es klingt ist es aber nicht. '''Texture Loader''' sind meist recht vielfältige Tools. Viele von ihnen ermöglichen es dem Nutzer Bilder verschiedener Bildformate (wie z.B. *.jpg, *.tga, *.png etc) zu Laden und als Texture zur Verfügung zu stellen.&lt;br /&gt;
&lt;br /&gt;
Man kann sich leicht vorstellen, dass der '''Texture Loader''' für jedes Bildformat seine Ladeprocedur anpassen muss. (Ein nicht zu unterschätzender Aspect, wenn man selber einmal einen '''Texture Loader''' schreiben will.)&lt;br /&gt;
&lt;br /&gt;
==Wie schreibe ich einen Texture Loader?==&lt;br /&gt;
Am besten gar nicht! &amp;lt;br&amp;gt;&lt;br /&gt;
Es gibt schon eine Menge leistungsfähige '''Texture Loader'''. (z.B. &amp;quot;glBitmap.pas&amp;quot; welcher aus der DGL Comunity stammt.) Wenn die Funktionen von keinem Loader deinen Ansprüchen genügen, dann nimm den der diesen am nächsten kommt und erweitere ihn entsprechend.&lt;br /&gt;
&lt;br /&gt;
Wenn es unabdingbar ist, dass der '''Texture Loader''' selber geschrieben sein muss, dann hier ein paar Tips:&lt;br /&gt;
* Verwende für die Texturen Klassen&lt;br /&gt;
* Ermögliche das Laden aus Streams. Damit wird dein Loader vielseitiger.&lt;br /&gt;
* Die wichtigsten Bildformate für Texturen sind *.bmp, *.jpg, *.tga, *.png&lt;br /&gt;
* Informationen zu den Bildformaten findest du auf [http://www.wotsit.org wotsit.org]&lt;br /&gt;
&lt;br /&gt;
(Es kann nie schaden sich einmal den Code eines bestehenden '''Texture Loader''' anzusehen.)&lt;br /&gt;
&lt;br /&gt;
Außerdem sind die folgenden Befehle sicherlich wichtig:&lt;br /&gt;
&lt;br /&gt;
==Wichtige OpenGL Befehle==&lt;br /&gt;
&lt;br /&gt;
[[glGenTextures]], [[glDeleteTextures]], [[glBindTexture]], [[glTexParameter]], [[glTexImage1D]], [[glTexImage2D]], [[glTexEnv]], [[glTexGen]]&lt;br /&gt;
&lt;br /&gt;
==Bestehende Texture Loader==&lt;br /&gt;
(Loader für Delphi)&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! Name (Link) || Features, Beschreibung&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|[[Glbitmap_loader|glBitmap.pas]]&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
|'''Pro'''&lt;br /&gt;
*Ist objektorientiert und verfügt über ein leicht erweiterbares Klassenmodel&lt;br /&gt;
*Benutzt von Hause aus die [[DGLOpenGL.pas]]&lt;br /&gt;
*Lädt seine Daten ausschließlich aus Streams. Er bietet aber für so ziemlich alle Fälle bereits eine Kappselung. So zum Beispiel für Dateien, Resourcen (Name oder ID) oder aber auch für TBitmaps.&lt;br /&gt;
*Unterscheidet anhand des Inhaltes welches Format ihm vor liegt.&lt;br /&gt;
*Bietet verschiedene Möglichkeiten die Texturen vor dem Generieren zu Manipulieren. Es besteht die Möglichkeit eine Methode zu übergeben die für jedes Pixel aufgerufen wird.&lt;br /&gt;
*Alphakanal kann mit hilfe einer übergebbaren Methode erzeugt werden.&lt;br /&gt;
*Texturen können dynamisch erzeugt werden (Mit hilfe der selben Methoden wie beim Manipulieren)&lt;br /&gt;
*Texturen werden ausschließlich so generiert wie sie dem Loader vorliegen. Es wir kein Alphakanal erstellt wenn keiner in der Textur vorhanden ist.&lt;br /&gt;
'''Contra'''&lt;br /&gt;
*Projekte werden durch die verwendenten Biblioheken größer als dem ein oder anderen lieb ist&lt;br /&gt;
*Klassenschnittstelle kann auf unerfahrene Entwickler, aufgrund ihrer Größe, verwirrend wirken. Wer allerdings grundlegende Kenntnisse in OOP hat wird problemlos eine Textur erstellen/laden und binden können.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|[http://www.sulaco.co.za/opengl5.htm##bmp Textures.pas]&lt;br /&gt;
|Von der Textures.pas existieren die verschiedensten Modifikationen. Unter anderem auch eine die Texturen aus Streams laden kann. Diese Versionen sind aber alle nicht offiziel und werden auch nicht publiziert.&lt;br /&gt;
'''Pro'''&lt;br /&gt;
*Sehr einfache Schnittstelle. Besteht aus einer einzigen Methode die einen Datei oder Resourcenamen entgegen nimmt und eine TexturID zurück liefert&lt;br /&gt;
*Anwendung wird nicht so groß, da auf einen Großteil der Bibliotheken von Delphi verzichtet wurde&lt;br /&gt;
*Importiert die benötigten OpenGL Methoden zum generieren statisch. Somit ist der Loader unabhängig von dem benutzten OpenGL Header.&lt;br /&gt;
'''Contra'''&lt;br /&gt;
*Ist nicht in der Lage aus Streams zu laden&lt;br /&gt;
*Erkennt den Dateitypen ausschließlich anhand des Datei oder Resourcenamen. Bei Resourcen muss eine Endung angegeben werden die von dem Loader wieder abgeschnitten wird.&lt;br /&gt;
*Die Texturen werden immer mit einem einheitlichen Format generiert. Je nach Anpassumg im Quelltext wird entweder immer ein Alphakanal erzeugt oder eben nicht.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|glBMP.pas &lt;br /&gt;
|Die ursprüngliche Seite des Autors ist leider nicht mehr verfügbar, der Loader kann aber aus dem [[DGL-SDK]] bezogen werden.&lt;br /&gt;
&lt;br /&gt;
Bei der glBMP.pas handelt es sich lediglich um die Textures.pas bei der die grundlegenden Funktionalität übernommen und in eine (relativ bescheidene) Klassenstruktur gepackt und erweitert wurde.&lt;br /&gt;
&lt;br /&gt;
'''Pro'''&lt;br /&gt;
*Ist objektorientiert&lt;br /&gt;
*Bietet verschiedene Möglichkeiten die Texturen vor dem Generieren zu Manipulieren.&lt;br /&gt;
*Alphakanal kann mit hilfe einer übergebbaren Methode erzeugt werden.&lt;br /&gt;
'''Contra'''&lt;br /&gt;
*Klassenmodel lässt sich nicht erweitern ohne in die bestehenden Quellen einzugreifen&lt;br /&gt;
*Bitmapdaten der Textur befinden sich auch nach dem Generieren der Textur im Clientspeicher&lt;br /&gt;
*Ist nicht in der Lage aus Streams zu laden&lt;br /&gt;
*Erkennt den Dateitypen ausschließlich anhand des Dateinamen.&lt;br /&gt;
*Kann ausschließlich nur Dateien laden.&lt;br /&gt;
*Die Texturen werden immer mit einem einheitlichen Format generiert. Texturen werden immer mit Alphakanal erzeugt.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7786</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7786"/>
				<updated>2005-06-16T14:37:48Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Warum das Ganze und wo kann ich sie finden? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu spiegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7750</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7750"/>
				<updated>2005-06-16T13:35:04Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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]]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; 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. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Also Bild laden, evtl bearbeiten und dann an OpenGL übergeben.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt; Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird. &amp;lt;i&amp;gt;&amp;lt;b&amp;gt;Die CubeMap ist nur dann einsetzbar, wenn alle Maps erfolgreich mit Daten versorgt wurden.&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&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;
== 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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7749</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7749"/>
				<updated>2005-06-16T13:19:45Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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]]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&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. Aus Übersichtsgründen erkläre ich nur das Laden eines Teiles der Cubemap. Der Rest sollte ja selbsterklärend sein.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die automatische Generation der Texturkoordinaten aktivieren kann. Standard ist dieses eingeschalten wodurch ein zusätzlicher Aufruf entfällt.&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7748</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7748"/>
				<updated>2005-06-16T13:14:15Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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]]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur und entsprechendes Target wird aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 LoadTexture('&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. Aus Übersichtsgründen erkläre ich nur das Laden eines Teiles der Cubemap. Der Rest sollte ja selbsterklärend sein.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die automatische Generation der Texturkoordinaten aktivieren kann. Standard ist dieses eingeschalten wodurch ein zusätzlicher Aufruf entfällt.&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7747</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7747"/>
				<updated>2005-06-16T13:04:37Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: Link angepasst&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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]]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wird und entsprechendes Target gleich aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 LoadTexture('&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. Aus Übersichtsgründen erkläre ich nur das Laden eines Teiles der Cubemap. Der Rest sollte ja selbsterklärend sein.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die automatische Generation der Texturkoordinaten aktivieren kann. Standard ist dieses eingeschalten wodurch ein zusätzlicher Aufruf entfällt.&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7746</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7746"/>
				<updated>2005-06-16T11:32:53Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: /* Das leidige Thema Alphakanal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 [http://www.dev-center.de/index.php?cat=header&amp;amp;file=glbitmap meiner Webseite]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wird und entsprechendes Target gleich aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 LoadTexture('&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. Aus Übersichtsgründen erkläre ich nur das Laden eines Teiles der Cubemap. Der Rest sollte ja selbsterklärend sein.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die automatische Generation der Texturkoordinaten aktivieren kann. Standard ist dieses eingeschalten wodurch ein zusätzlicher Aufruf entfällt.&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7745</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7745"/>
				<updated>2005-06-16T11:27:11Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&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 [http://www.dev-center.de/index.php?cat=header&amp;amp;file=glbitmap meiner Webseite]. Aber Vorsicht. Beide Quellen beinhalten noch nicht die neuste Version der glBitmap. Mitunter können einige Features noch nicht unterstützt werden oder sie haben andere Parameter.&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 &amp;lt;b&amp;gt;der obersten Zeile zu erst abgelegt&amp;lt;/b&amp;gt;. 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 &amp;lt;i&amp;gt;FlipVert&amp;lt;/i&amp;gt; die Möglichkeit die Textur zu siegeln. Näheres in Abschnitt &amp;lt;i&amp;gt;Texturen konfigurieren&amp;lt;/i&amp;gt;. 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) 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;
Es besteht auch die Möglichkeit, dass die Bilddaten dynamisch generiert oder mittels einer Instanz von TBitmap vorliegen. Diese Instanz muss dann aber als Pixelformat 24 oder 32 Bit haben.&lt;br /&gt;
&lt;br /&gt;
Um PNG's laden zu können muss eine externe Bibliothek namens [http://pngdelphi.sourceforge.net/ PNGImage] eingebunden und das Define &amp;lt;i&amp;gt;pngimage&amp;lt;/i&amp;gt; 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 &amp;lt;b&amp;gt;OpenGL richtig initialisiert worden sein muss&amp;lt;/b&amp;gt; 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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit wird die Datei &amp;lt;i&amp;gt;Wall.bmp&amp;lt;/i&amp;gt; geladen und die TextureID wird in die Variable &amp;lt;i&amp;gt;Texture&amp;lt;/i&amp;gt; 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 &amp;lt;i&amp;gt;GL_TEXTURE_2D&amp;lt;/i&amp;gt;. 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 = &amp;lt;b&amp;gt;class&amp;lt;/b&amp;gt;(TForm)&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Verschiene Elemente und Events des Fensters&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;private&amp;lt;/b&amp;gt;&lt;br /&gt;
   fTexture: TglBitmap2D; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz unserer Textur&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun müssen wir der Textur noch Leben einhauchen.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;b&amp;gt;procedure&amp;lt;/b&amp;gt; TForm1.FormShow(Sender: TObject);&lt;br /&gt;
 &amp;lt;b&amp;gt;begin&amp;lt;/b&amp;gt;&lt;br /&gt;
   &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// OpenGL Initialisieren&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
   fTexture := TglBitmap2D.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt; &lt;br /&gt;
 &amp;lt;b&amp;gt;end;&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz erstellen und Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
   fTexture.GenTexture; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// geladene Textur an OpenGL übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&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;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wird und entsprechendes Target gleich aktiviert.&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Textur wieder frei geben.&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei ist zu beachten, dass dies nach Möglichkeit &amp;lt;b&amp;gt;vor dem Löschen des Rendercontex&amp;lt;/b&amp;gt; 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 die 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]. Also mögliche Dateiformate kämen TGA's und PNG's 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. &amp;lt;b&amp;gt;Der Aufruf muss vor &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; stattfinden, da sonst die Textur bereits an OpenGL übergeben wurde.&amp;lt;/b&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal aus Datei laden&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;AddAlphaFromFunc&amp;lt;/i&amp;gt;. 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 &amp;lt;i&amp;gt;e = mc²&amp;lt;/i&amp;gt;&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Alphakanal anhand einer Farbe hinzufügen&amp;lt;/font&amp;gt;&amp;lt;/i&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 &amp;lt;i&amp;gt;Deviation&amp;lt;/i&amp;gt; bestimmt eine Abweichung um der die Farben abweichen dürfen um trotzdem noch als Transparent erkannt zu werden. Speziell für JPEG's 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;
== 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;DeleteTextureOnFree&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;FreeDataAfterGenTexture&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Target&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;Format&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ein Aufzählungstyp und er erlaubt 4 Werte. &lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfDefault&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf16Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 16Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tf32Bit&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Hier wird die Textur in 32Bit abgelegt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;tfCompressed&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;&amp;lt;i&amp;gt;MipMap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; ist ebenfalls ein Aufzählungstyp und er erlaubt 3 Werte.&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; rules=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmNone&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Wie man vermuten könnte werden hierbei keine Mipmaps erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmap&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;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.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;mmMipmapGlu&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;In diesem Falle werden die [[Mipmaps]] ausschließlich mit der GLU erstellt.&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mithilfe der Methoden &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetFilter&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; und &amp;lt;b&amp;gt;&amp;lt;i&amp;gt;SetWrap&amp;lt;/i&amp;gt;&amp;lt;/b&amp;gt; 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 [[gTexParameter]] 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;
== e = mc² ==&lt;br /&gt;
&lt;br /&gt;
{ Funktionsschnittstelle, Arbeitsweise, Möglichkeiten, Beispiele }&lt;br /&gt;
&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;
 &amp;lt;b&amp;gt;var&amp;lt;/b&amp;gt;&lt;br /&gt;
   Texture: TGLuint;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Cubemaps laden&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
 LoadTexture('&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. Aus Übersichtsgründen erkläre ich nur das Laden eines Teiles der Cubemap. Der Rest sollte ja selbsterklärend sein.&lt;br /&gt;
&lt;br /&gt;
 fCubeMap := TglBitmapCubeMap.Create; &amp;lt;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Instanz der Klasse erstellen&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Datei Laden&amp;lt;/font&amp;gt;&amp;lt;/i&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;i&amp;gt;&amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;// Einzelnen Teil übergeben&amp;lt;/font&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn die Textur also bereit zum Übergeben ist, dann müssen wir &amp;lt;i&amp;gt;GenerateCubeMap&amp;lt;/i&amp;gt; mit dem entsprechenden Teil der Cubemap aufrufen. In diesem Falle ist es die positive X Achse. Die Reihenfolge der Maps spielt hierbei keine Rolle. Wichtig ist nur, dass sie die selbe Auflösung und das selbe Format haben. Die Methode &amp;lt;i&amp;gt;GenTexture&amp;lt;/i&amp;gt; steht bei dieser Klasse nicht zur Verfügung, da beim ersten Aufruf von GenerateCubeMap automatisch die OpenGL Textur erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Beim Binden der CubeMap existiert ein zusätzlicher Parameter mit dem man die automatische Generation der Texturkoordinaten aktivieren kann. Standard ist dieses eingeschalten wodurch ein zusätzlicher Aufruf entfällt.&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 BMP's 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 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 über 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>Lossy eX</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7743</id>
		<title>Glbitmap loader</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Glbitmap_loader&amp;diff=7743"/>
				<updated>2005-06-16T11:19:01Z</updated>
		
		<summary type="html">&lt;p&gt;Lossy eX: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{unvollständig}}&lt;br /&gt;
&lt;br /&gt;
[http://www.dev-center.de/ |meiner Webseite]&lt;/div&gt;</summary>
		<author><name>Lossy eX</name></author>	</entry>

	</feed>