~sladen/openbve/openbve2

« back to all changes in this revision

Viewing changes to OpenBve/Graphics/Textures.cs

  • Committer: Paul Sladen
  • Author(s): Michelle Boucquemont
  • Date: 2010-03-17 04:04:44 UTC
  • Revision ID: git-v1:c9050dde4c55fe2b9c257080653cee1a07c91303
import openbve2.zip (2010-03-14)

You will find a settings.cfg file where you can configure a series of
options and also which route or object to load. The options are
explained briefly via the comments in the settings.cfg file itself.
Select any route or object you want, but mind the following limitations:

* Background images and fog are not yet supported. Only a background
  color will be shown.
* Animated objects are not yet supported. This includes signals. These
  objects are not shown at all.
* Glow is not yet supported. All objects using glow will always show at
  full intensity instead of fading in.
* The legacy visibility system (where objects are disposed of as soon as
  the CSV/RW block the object was placed in has been passed by the camera)
  is not yet supported, only the new 2D grid is.

In-game, you can use the arrow, the WASD and the PageUp and PageDown keys to move and rotate around. Hold down the shift, control or alt key for faster movement. There is no way for you to jump to specific "track positions" as the new program does not have something like them internally. Also, you cannot jump to stations in any way at the moment. The initial position of the camera is the first stop point, though.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
                 * Registered textures are identified by their file or folder names, the plugin that is supposed
22
22
                 * to load the texture, and via additional properties. If a texture with the same properties
23
23
                 * is registered multiple times, it will in fact only reuse the already registered texture. This
24
 
                 * means that this texture manager only stores and managed each unique texture once.
 
24
                 * means that this texture manager only stores and manages each unique texture once.
25
25
                 * 
26
26
                 * Generally, plugins will indirectly call RegisterTexture to register a texture and acquire a
27
27
                 * handle to refer to this texture for later use. The renderer, or more precisely, the object
33
33
                 * in Textures_Helper.cs for easier maintenance.
34
34
                 * 
35
35
                 * TODO: Not all functions in this file have been completely implemented yet.
 
36
                 * TODO: The XML documentation in this file is still incomplete.
36
37
                 * 
37
38
                 * */
38
39
                
 
40
                // api handle
 
41
                /// <summary>Represents a handle to a texture.</summary>
 
42
                /// <remarks>This class is used for interaction with the API.</remarks>
 
43
                internal class ApiHandle : OpenBveApi.Texture.TextureHandle {
 
44
                        /// <summary>The index to the texture.</summary>
 
45
                        internal int TextureIndex;
 
46
                        /// <summary>Creates a new instance of this class.</summary>
 
47
                        /// <param name="libraryIndex">The index to the texture.</param>
 
48
                        internal ApiHandle(int textureIndex) {
 
49
                                this.TextureIndex = textureIndex;
 
50
                        }
 
51
                }
 
52
                
39
53
                // texture type
40
54
                internal enum TextureType {
41
55
                        Unknown = 0,
42
56
                        Opaque = 1,
43
 
                        TransparentColor = 2,
 
57
                        Transparent = 2,
44
58
                        Alpha = 3
45
59
                }
46
60
                
85
99
                /// <summary>Registers a texture and returns the associated texture index.</summary>
86
100
                /// <param name="origin">The origin of the texture. If a path is provided, it must be an absolute path.</param>
87
101
                /// <param name="parameters">The parameters for the texture.</param>
88
 
                /// <param name="textureIndex">Receives the managed texture index on success.</param>
 
102
                /// <param name="textureIndex">Receives the managed texture index.</param>
89
103
                internal static void RegisterTexture(OpenBveApi.General.Origin origin, OpenBveApi.Texture.TextureParameters parameters, out int textureIndex) {
90
104
                        int index;
91
105
                        if (FindTexture(origin, parameters, out index)) {
92
 
                                // texture already exists
93
106
                                textureIndex = index;
94
107
                        } else {
95
 
                                // register new texture
96
108
                                if (RegisteredTextures.Length == RegisteredTextureCount) {
97
109
                                        Array.Resize<Texture>(ref RegisteredTextures, RegisteredTextures.Length << 1);
98
110
                                }
110
122
                        }
111
123
                }
112
124
                
 
125
                // register and load texture
 
126
                /// <summary>Registers and loads a texture directly from raw data.</summary>
 
127
                /// <param name="raw">The width of the texture.</param>
 
128
                /// <param name="raw">The height of the texture.</param>
 
129
                /// <param name="raw">The raw texture data.</param>
 
130
                /// <param name="textureIndex">Receives the managed texture index.</param>
 
131
                /// <param name="openGlTextureIndex">Receives the OpenGL texture index.</param>
 
132
                internal static void RegisterAndLoadTexture(int width, int height, byte[] raw, out int textureIndex, out int openGlTextureIndex) {
 
133
                        if (RegisteredTextures.Length == RegisteredTextureCount) {
 
134
                                Array.Resize<Texture>(ref RegisteredTextures, RegisteredTextures.Length << 1);
 
135
                        }
 
136
                        textureIndex = RegisteredTextureCount;
 
137
                        RegisteredTextures[RegisteredTextureCount] = new Texture();
 
138
                        RegisteredTextures[RegisteredTextureCount].Origin = OpenBveApi.General.Origin.Empty;
 
139
                        RegisteredTextures[RegisteredTextureCount].Parameters = OpenBveApi.Texture.TextureParameters.ClampToEdge;
 
140
                        RegisteredTextures[RegisteredTextureCount].RawData = raw;
 
141
                        RegisteredTextures[RegisteredTextureCount].RawWidth = width;
 
142
                        RegisteredTextures[RegisteredTextureCount].RawHeight = height;
 
143
                        RegisteredTextures[RegisteredTextureCount].Type = TextureType.Alpha;
 
144
                        RegisteredTextures[RegisteredTextureCount].Status = TextureStatus.Finalizing;
 
145
                        RegisteredTextures[RegisteredTextureCount].OpenGlTextureIndex = 0;
 
146
                        SubmitRawDataToOpenGl(RegisteredTextureCount, false);
 
147
                        RegisteredTextures[RegisteredTextureCount].Status = TextureStatus.Loaded;
 
148
                        textureIndex = RegisteredTextureCount;
 
149
                        openGlTextureIndex = RegisteredTextures[RegisteredTextureCount].OpenGlTextureIndex;
 
150
                        RegisteredTextureCount++;
 
151
                }
 
152
                
113
153
                // find texture
114
 
                /// <summary>Finds a texture of a given file name and load options, receives the texture index in an output parameter, and returns the success of the operation.</summary>
 
154
                /// <summary>Finds a texture of a specified file name and load options, receives the texture index in an output parameter, and returns the success of the operation.</summary>
115
155
                /// <param name="origin">The texture origin to search for.</param>
116
156
                /// <param name="parameters">The texture parameters to search for.</param>
117
157
                /// <param name="textureIndex">Receives the texture index if the texture was found.</param>
120
160
                        if (origin.Path != null) {
121
161
                                for (int i = 0; i < RegisteredTextureCount; i++) {
122
162
                                        if (RegisteredTextures[i] != null && RegisteredTextures[i].Origin.Path != null) {
123
 
                                                if (OpenBveApi.General.Origin.Equals(Interfaces.Host10, RegisteredTextures[i].Origin, origin)) {
 
163
                                                if (OpenBveApi.General.Origin.Equals(RegisteredTextures[i].Origin, origin)) {
124
164
                                                        if (RegisteredTextures[i].Parameters == parameters) {
125
165
                                                                textureIndex = i;
126
166
                                                                return true;
133
173
                        return false;
134
174
                }
135
175
 
136
 
                // use texture
137
 
                internal static int UseTexture(int TextureIndex) {
138
 
                        switch(RegisteredTextures[TextureIndex].Status) {
139
 
                                case TextureStatus.NotLoaded:
140
 
                                        // not loaded
141
 
                                        LoadTextureRawData(TextureIndex);
142
 
                                        SubmitRawDataToOpenGl(TextureIndex);
143
 
                                        return RegisteredTextures[TextureIndex].OpenGlTextureIndex;
144
 
                                case TextureStatus.Scheduled:
145
 
                                        // scheduled - wait for the background worker to complete loading
146
 
                                        while (RegisteredTextures[TextureIndex].Status == TextureStatus.Scheduled) {
147
 
                                                System.Threading.Thread.Sleep(0);
 
176
                // load texture
 
177
                /// <summary>Loads a registered texture immediately or via the background worker.</summary>
 
178
                /// <param name="textureIndex">The index of the registered texture.</param>
 
179
                /// <param name="loadImmediately">Whether to load the texture immediately or via the background worker.</param>
 
180
                internal static void LoadTexture(int textureIndex, bool loadImmediately) {
 
181
                        if (loadImmediately) {
 
182
                                switch(RegisteredTextures[textureIndex].Status) {
 
183
                                        case TextureStatus.NotLoaded:
 
184
                                                // not loaded
 
185
                                                LoadTextureRawData(textureIndex);
 
186
                                                SubmitRawDataToOpenGl(textureIndex, true);
 
187
                                                RegisteredTextures[textureIndex].Status = TextureStatus.Loaded;
 
188
                                                break;
 
189
                                        case TextureStatus.Scheduled:
 
190
                                                // scheduled - wait for the background worker to complete loading
 
191
                                                while (RegisteredTextures[textureIndex].Status != TextureStatus.Finalizing) {
 
192
                                                        System.Threading.Thread.Sleep(0);
 
193
                                                }
 
194
                                                SubmitRawDataToOpenGl(textureIndex, true);
 
195
                                                break;
 
196
                                        case TextureStatus.Finalizing:
 
197
                                                // finalizing
 
198
                                                SubmitRawDataToOpenGl(textureIndex, true);
 
199
                                                RegisteredTextures[textureIndex].Status = TextureStatus.Loaded;
 
200
                                                break;
 
201
                                }
 
202
                        } else {
 
203
                                throw new NotImplementedException("This operation cannot be performed because the background worker is not yet implemented.");
 
204
                                /*
 
205
                                        if (RegisteredTextures[textureIndex].Status == TextureStatus.NotLoaded) {
 
206
                                                // let the background worker load the texture
 
207
                                                RegisteredTextures[textureIndex].Status = TextureStatus.Scheduled;
148
208
                                        }
149
 
                                        SubmitRawDataToOpenGl(TextureIndex);
150
 
                                        return RegisteredTextures[TextureIndex].OpenGlTextureIndex;
151
 
                                case TextureStatus.Finalizing:
152
 
                                        // finalizing
153
 
                                        SubmitRawDataToOpenGl(TextureIndex);
154
 
                                        return RegisteredTextures[TextureIndex].OpenGlTextureIndex;
155
 
                                case TextureStatus.Loaded:
156
 
                                        // loaded
157
 
                                        return RegisteredTextures[TextureIndex].OpenGlTextureIndex;
158
 
                                        break;
159
 
                                default:
160
 
                                        // invalid texture status
161
 
                                        throw new InvalidOperationException();
 
209
                                 */
 
210
                        }
 
211
                }
 
212
                
 
213
                // get opengl texture index
 
214
                /// <summary>Gets the OpenGL texture index for a registered texture provided that the texture has been loaded into OpenGL.</summary>
 
215
                /// <param name="textureIndex">The index of the registered texture.</param>
 
216
                /// <param name="openGlTextureIndex">Receives the OpenGL texture index.</param>
 
217
                /// <returns>A boolean indicating the success of the operation.</returns>
 
218
                internal static bool GetOpenGlTextureIndex(int textureIndex, out int openGlTextureIndex) {
 
219
                        if (RegisteredTextures[textureIndex].Status == TextureStatus.Loaded) {
 
220
                                openGlTextureIndex = RegisteredTextures[textureIndex].OpenGlTextureIndex;
 
221
                                return true;
 
222
                        } else {
 
223
                                openGlTextureIndex = 0;
 
224
                                return false;
162
225
                        }
163
226
                }
164
227
                
165
228
                // load texture raw data
166
 
                /// <summary>Loads the raw data of a registered texture. The texture status must be NeverLoaded, Queried or Unloaded.</summary>
 
229
                /// <summary>Loads the raw data of a registered texture. The texture status must be NotLoaded or Scheduled.</summary>
167
230
                /// <param name="TextureIndex">The index to the registered texture.</param>
168
 
                /// <exception cref="InvalidOperationException">Raised when the status of the registered texture is not NeverLoaded, Queried or Unloaded.</exception>
 
231
                /// <exception cref="InvalidOperationException">Raised when the status of the registered texture is neither NotLoaded nor Scheduled.</exception>
169
232
                /// <remarks>When this operation completes, the status of the registered texture is set to Finalizing.</remarks>
170
 
                internal static void LoadTextureRawData(int TextureIndex) {
 
233
                internal static void LoadTextureRawData(int textureIndex) {
171
234
                        if (
172
 
                                RegisteredTextures[TextureIndex].Status == TextureStatus.NotLoaded |
173
 
                                RegisteredTextures[TextureIndex].Status == TextureStatus.Scheduled
 
235
                                RegisteredTextures[textureIndex].Status == TextureStatus.NotLoaded |
 
236
                                RegisteredTextures[textureIndex].Status == TextureStatus.Scheduled
174
237
                        ) {
175
238
                                // load texture
176
 
                                OpenBveApi.General.Origin origin = RegisteredTextures[TextureIndex].Origin;
177
 
                                OpenBveApi.Texture.TextureParameters parameters = RegisteredTextures[TextureIndex].Parameters;
 
239
                                OpenBveApi.General.Origin origin = RegisteredTextures[textureIndex].Origin;
 
240
                                OpenBveApi.Texture.TextureParameters parameters = RegisteredTextures[textureIndex].Parameters;
178
241
                                OpenBveApi.Texture.TextureData texture;
179
 
                                Interfaces.Host10.LoadTexture(origin, out texture);
180
 
                                // convert to 8 bits per channel
181
 
                                byte[] raw;
182
 
                                ConvertTo8BitsPerChannel(texture, out raw);
183
 
                                int width = texture.Format.Width;
184
 
                                int height = texture.Format.Height;
185
 
                                // extract clip
186
 
                                if (parameters.ClipRegion != null) {
187
 
                                        ExtractClipRegion(ref width, ref height, ref raw, parameters.ClipRegion);
188
 
                                }
189
 
                                // remove transparent color
190
 
                                if (parameters.TransparentColor.Assigned) {
 
242
                                if (Interfaces.Host10.LoadTexture(origin, out texture) == OpenBveApi.General.Result.Successful) {
 
243
                                        // convert to 8 bits per channel
 
244
                                        byte[] raw;
 
245
                                        ConvertTo8BitsPerChannel(texture, out raw);
 
246
                                        int width = texture.Format.Width;
 
247
                                        int height = texture.Format.Height;
 
248
                                        // extract clip
 
249
                                        if (parameters.ClipRegion != null) {
 
250
                                                ExtractClipRegion(ref width, ref height, ref raw, parameters.ClipRegion);
 
251
                                        }
 
252
                                        // eliminate transparent color
191
253
                                        EliminateTransparentColor(width, height, ref raw, parameters.TransparentColor);
 
254
                                        // convert to power-of-two
 
255
                                        ConvertToPowerOfTwoSize(ref width, ref height, ref raw);
 
256
                                        // determine texture type
 
257
                                        RegisteredTextures[textureIndex].Type = DetermineTextureType(width, height, raw);
 
258
                                        // store data
 
259
                                        RegisteredTextures[textureIndex].RawWidth = width;
 
260
                                        RegisteredTextures[textureIndex].RawHeight = height;
 
261
                                        RegisteredTextures[textureIndex].RawData = raw;
 
262
                                        RegisteredTextures[textureIndex].Status = TextureStatus.Finalizing;
 
263
                                } else {
 
264
                                        // loading failed
 
265
                                        RegisteredTextures[textureIndex].Type = TextureType.Opaque;
 
266
                                        RegisteredTextures[textureIndex].RawWidth = 32;
 
267
                                        RegisteredTextures[textureIndex].RawHeight = 8;
 
268
                                        RegisteredTextures[textureIndex].RawData = new byte[] {
 
269
                                                /* white "error" on red background */
 
270
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
271
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
272
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
273
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
274
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
275
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
276
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF,
 
277
                                                0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF
 
278
                                        };
 
279
                                        RegisteredTextures[textureIndex].Status = TextureStatus.Finalizing;
192
280
                                }
193
 
                                // convert to power-of-two
194
 
                                ConvertToPowerOfTwoSize(ref width, ref height, ref raw);
195
 
                                // store data
196
 
                                RegisteredTextures[TextureIndex].RawWidth = width;
197
 
                                RegisteredTextures[TextureIndex].RawHeight = height;
198
 
                                RegisteredTextures[TextureIndex].RawData = raw;
199
 
                                RegisteredTextures[TextureIndex].Status = TextureStatus.Finalizing;
200
281
                        } else {
201
282
                                // invalid texture status
202
283
                                throw new InvalidOperationException();
205
286
                
206
287
                // submit raw data to opengl
207
288
                /// <summary>Submits the raw data of a registered texture to OpenGL. The texture status must be Finalizing.</summary>
208
 
                /// <param name="TextureIndex">The index to the registered texture.</param>
209
 
                /// <exception cref="InvalidOperationException">Raised when the status of the registered texture is not Finalizing.</exception>
210
 
                /// <remarks>When this operation completes, the status of the registered texture is set to Loaded.</remarks>
211
 
                internal static void SubmitRawDataToOpenGl(int TextureIndex) {
 
289
                /// <param name="textureIndex">The index to the registered texture.</param>
 
290
                /// <param name="respectQuality">Whether to respect the global texture quality setting. If set to False, bilinear filtering is used without mipmapping.</param>
 
291
                internal static void SubmitRawDataToOpenGl(int textureIndex, bool respectQuality) {
212
292
                        int[] names = new int[1];
213
293
                        Gl.glGenTextures(1, names);
214
 
                        RegisteredTextures[TextureIndex].OpenGlTextureIndex = names[0];
215
 
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, RegisteredTextures[TextureIndex].OpenGlTextureIndex);
216
 
                        
217
 
                        // filter
218
 
                        // TODO: Implement this.
219
 
 
220
 
//                      switch (Options.CurrentOptions.TextureInterpolationMode) {
221
 
//                              case Options.TextureInterpolationMode.NearestNeighbor:
222
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
223
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
224
 
//                                      break;
225
 
//                              case Options.TextureInterpolationMode.NearestNeighborMipmapping:
226
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_NEAREST);
227
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
228
 
//                                      break;
229
 
//                              case Options.TextureInterpolationMode.Bilinear:
230
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
231
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
232
 
//                                      break;
233
 
//                              case Options.TextureInterpolationMode.BilinearMipmapping:
234
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
235
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
236
 
//                                      break;
237
 
//                              case Options.TextureInterpolationMode.Trilinear:
238
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
239
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
240
 
//                                      break;
241
 
//                              default:
242
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
243
 
//                                      Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
244
 
//                                      break;
245
 
//                      }
246
 
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
247
 
                        Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
248
 
                        
249
 
                        // wrap mode
250
 
                        if (RegisteredTextures[TextureIndex].Parameters.HorizontalWrapMode == OpenBveApi.Texture.TextureWrapMode.ClampToEdge) {
 
294
                        RegisteredTextures[textureIndex].OpenGlTextureIndex = names[0];
 
295
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, names[0]);
 
296
                        if (respectQuality) {
 
297
                                switch (Program.CurrentOptions.InterpolationMode) {
 
298
                                        case Options.TextureInterpolationMode.NearestNeighbor:
 
299
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
 
300
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
 
301
                                                break;
 
302
                                        case Options.TextureInterpolationMode.NearestNeighborMipmapped:
 
303
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_NEAREST);
 
304
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
 
305
                                                break;
 
306
                                        case Options.TextureInterpolationMode.Bilinear:
 
307
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
 
308
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
 
309
                                                break;
 
310
                                        case Options.TextureInterpolationMode.BilinearMipmapped:
 
311
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
 
312
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
 
313
                                                break;
 
314
                                        case Options.TextureInterpolationMode.TrilinearMipmapped:
 
315
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
 
316
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
 
317
                                                break;
 
318
                                        default:
 
319
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
 
320
                                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
 
321
                                                break;
 
322
                                }
 
323
                        } else {
 
324
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
 
325
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);
 
326
                        }
 
327
                        if (Program.CurrentOptions.InterpolationMode == Options.TextureInterpolationMode.AnisotropicFiltering & Program.AnisotropicMaximum != 0.0f) {
 
328
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Program.AnisotropicMaximum);
 
329
                        }
 
330
                        /*
 
331
                         * Set the wrap mode.
 
332
                         * */
 
333
                        if (RegisteredTextures[textureIndex].Parameters.HorizontalWrapMode == OpenBveApi.Texture.TextureWrapMode.ClampToEdge) {
251
334
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
252
335
                        } else {
253
336
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
254
337
                        }
255
 
                        if (RegisteredTextures[TextureIndex].Parameters.VerticalWrapMode == OpenBveApi.Texture.TextureWrapMode.ClampToEdge) {
 
338
                        if (RegisteredTextures[textureIndex].Parameters.VerticalWrapMode == OpenBveApi.Texture.TextureWrapMode.ClampToEdge) {
256
339
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
257
340
                        } else {
258
341
                                Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
259
342
                        }
260
 
                        // submit
261
 
                        Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE);
262
 
                        int width = RegisteredTextures[TextureIndex].RawWidth;
263
 
                        int height = RegisteredTextures[TextureIndex].RawHeight;
264
 
                        byte[] raw = RegisteredTextures[TextureIndex].RawData;
265
 
                        Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, raw);
 
343
                        /*
 
344
                         * Submit the texture to OpenGL.
 
345
                         * */
 
346
                        if (respectQuality) {
 
347
                                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE);
 
348
                        } else {
 
349
                                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_GENERATE_MIPMAP, Gl.GL_TRUE);
 
350
                        }
 
351
                        int width = RegisteredTextures[textureIndex].RawWidth;
 
352
                        int height = RegisteredTextures[textureIndex].RawHeight;
 
353
                        byte[] raw = RegisteredTextures[textureIndex].RawData;
 
354
                        Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, raw);
266
355
                }
267
356
                
268
357
                // deinitializes