ecere/gfx/drivers/OpenGL/Default Shader: Fixed mistakes in lights 3,4,7
[sdk] / ecere / src / gfx / DisplaySystem.ec
1 namespace gfx;
2
3 #if !defined(__EMSCRIPTEN__)
4 import "Mutex"
5 #endif
6 import "Display"
7
8 const String printingDocumentName;
9
10 public void SetPrintingDocumentName(const String name)
11 {
12    printingDocumentName = name;
13 }
14
15 public class DisplaySystemResPtr : struct
16 {
17    DisplaySystemResPtr prev, next;
18    Resource resource;
19 };
20
21 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
22 static void FreeTexture(NamedLink texture)
23 {
24    Bitmap bitmap = texture.data;
25    bitmap.Free();
26    delete bitmap;
27    delete texture.name;
28 }
29
30 static void FreeMaterial(Material material)
31 {
32    delete material.name;
33 }
34 #endif
35
36 public class DisplaySystem
37 {
38 public:
39    class_no_expansion;
40    ~DisplaySystem()
41    {
42 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
43       OldLink mesh;
44
45       materials.Free(Material::Free);
46       textures.Free(FreeTexture);
47       for(mesh = meshes.first; mesh; mesh = mesh.next)
48          ((Mesh)mesh.data).Free(0);
49       meshes.Free(null);
50 #endif
51
52       if(driverData)
53          driver.DestroyDisplaySystem(this);
54
55       if(driver.displaySystem == this)
56          driver.displaySystem = null;
57    }
58
59    bool Create(const char * driverName, void * window, bool fullScreen)
60    {
61       bool result = false;
62       subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
63       if(displayDriver)
64       {
65          flags.fullScreen = fullScreen;
66          this.window = window;
67          if(displayDriver.CreateDisplaySystem(this))
68             result = true;
69
70          driver = displayDriver;
71          if(!result)
72          {
73             // LogErrorCode(GERR_DISPLAY_INIT_FAILED, driver);
74             displayDriver.displaySystem = null;
75          }
76          else if(!displayDriver.displaySystem)
77          {
78             displayDriver.displaySystem = this;
79          }
80       }
81       return result;
82    }
83
84    Font LoadOutlineFont(const char * faceName, float size, FontFlags flags, float outlineSize, float outlineFade)
85    {
86       Font result = null;
87       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
88       char * string = CopyString(faceName);
89       char *fonts[32];
90       if(string)
91       {
92          int numFonts = TokenizeWith(string, 32, fonts, ",", true);
93          int c;
94          for(c = 0; c<numFonts; c++)
95          {
96             TrimLSpaces(fonts[c],fonts[c]);
97             TrimRSpaces(fonts[c],fonts[c]);
98             if((result = driver.LoadFont(this, fonts[c], size, flags, outlineSize, outlineFade)))
99             {
100                break;
101             }
102          }
103          delete string;
104       }
105       return result;
106    }
107
108    Font LoadFont(const char * faceName, float size, FontFlags flags)
109    {
110       return LoadOutlineFont(faceName, size, flags, 0, 0);
111    }
112
113    void UnloadFont(Font font)
114    {
115       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
116       driver.UnloadFont(this, font);
117    }
118
119    void FontExtent(Font font, const char * text, int len, int * width, int * height)
120    {
121       if(this && text)
122       {
123          int advance = 0;
124          driver.FontExtent(this, font, text, len, width, height, 0, null, &advance);
125          if(width) *width += advance;
126       }
127       else
128       {
129          if(width) *width = 0;
130          if(height) *height = 0;
131       }
132    }
133
134    void FontExtent2(Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * overHang)
135    {
136       if(this && text)
137          driver.FontExtent(this, font, text, len, width, height, prevGlyph, rPrevGlyph, overHang);
138       else
139       {
140          if(width) *width = 0;
141          if(height) *height = 0;
142       }
143    }
144
145    void * LoadResource(Resource resource)
146    {
147       DisplaySystemResPtr res;
148       for(res = resources.first; res; res = res.next)
149       {
150          Resource existing = res.resource;
151
152          if(existing._class == resource._class)
153          {
154             if(resource.OnCompare(existing) == 0)
155                break;
156          }
157       }
158       if(!res)
159       {
160          // res = DisplaySystemResPtr { resource = new classof(resource) };
161          res = DisplaySystemResPtr { resource = eInstance_New(resource._class) };
162          resources.Add(res);
163
164          // This will load e.g. the Bitmap *
165          res.resource.Load(resource, this);
166       }
167       // This would copy e.g. the Bitmap *
168       incref res.resource;
169       resource.Reference(res.resource);
170
171       return res;
172    }
173
174    void UnloadResource(Resource resource, DisplaySystemResPtr res)
175    {
176       // This would clear e.g. the Bitmap *
177       resource.Dereference();
178       if(res)
179       {
180          if(res.resource._refCount == 1)
181          {
182             delete res.resource;
183             resources.Delete(res);
184          }
185          else
186             res.resource._refCount--;
187       }
188    }
189
190    bool Lock()
191    {
192       bool result = false;
193 #if !defined(__EMSCRIPTEN__)
194       mutex.Wait();
195 #endif
196
197       if(!current)
198          result = driver.LockSystem(this);
199       else
200          result = true;
201       current++;
202       return result;
203    }
204
205    void Unlock(void)
206    {
207       current--;
208       if(!current)
209          driver.UnlockSystem(this);
210
211 #if !defined(__EMSCRIPTEN__)
212       mutex.Release();
213 #endif
214    }
215 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
216    // --- Materials List Management ---
217
218    Material AddNamedMaterial(const char * name)
219    {
220       Material material = materials.FindName(name, false);
221       if(!material)
222       {
223          material = Material { };
224          if(material)
225          {
226             material.name = CopyString(name);
227             if(name)
228                materials.AddName(material);
229             else
230                materials.Add(material);
231          }
232       }
233       return material;
234    }
235
236    bool AddMaterial(Material material)
237    {
238       if(material.name)
239          materials.AddName(material);
240       else
241          materials.Add(material);
242       return true;
243    }
244
245    Material GetMaterial(const char * name)
246    {
247       return materials.FindName(name, false);
248    }
249
250    bool RemoveMaterial(Material material)
251    {
252       delete material.name;
253       materials.Delete(material);
254       return true;
255    }
256
257    void ClearMaterials()
258    {
259       materials.Free(FreeMaterial);
260    }
261
262    // --- Textures List Management ---
263
264    NamedLink AddTexture(const char * name, Bitmap bitmap)
265    {
266       NamedLink item { };
267       if(item)
268       {
269          item.data = bitmap;
270          incref bitmap;
271          item.name = new char[strlen(name) + 1];
272          strcpy(item.name, name);
273          textures.AddName(item);
274       }
275       return item;
276    }
277
278    Bitmap GetTexture(const char * name)
279    {
280       return textures.FindNamedLink(name, false);
281    }
282
283    bool RemoveTexture(const char * name)
284    {
285       NamedLink item = textures.FindName(name, false);
286       if(item)
287       {
288          FreeTexture(item);
289          textures.Delete(item);
290          return true;
291       }
292       return false;
293    }
294
295    void ClearTextures()
296    {
297       textures.Free(FreeTexture);
298    }
299
300    // --- Meshes List Management ---
301
302    OldLink AddMesh(Mesh mesh)
303    {
304       if(this)
305       {
306          OldLink item { };
307          if(item)
308          {
309             item.data = mesh;
310             mesh.displaySystem = this;
311             meshes.Add(item);
312          }
313          return item;
314       }
315       return null;
316    }
317
318    bool RemoveMesh(Mesh mesh)
319    {
320       OldLink item = meshes.FindLink(mesh);
321       if(item)
322       {
323          mesh.Free(0);
324          meshes.Delete(item);
325          return true;
326       }
327       return false;
328    }
329
330    void ClearMeshes()
331    {
332       OldLink mesh;
333       for(mesh = meshes.first; mesh; mesh = mesh.next)
334          ((Mesh)mesh.data).Free(0);
335       meshes.Free(null);
336    }
337 #endif
338
339 private:
340    subclass(DisplayDriver) driver;
341    void * data;
342    void * window;
343    public PixelFormat pixelFormat;
344    public DisplayFlags flags;
345    int numDisplays;
346    GLCapabilities glCapabilities;
347
348    OldList resources;
349
350 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
351    // This will all go in resources
352    OldList materials;
353    OldList textures;
354    OldList meshes;
355 #endif
356
357    void * driverData;
358    int current;
359 #if !defined(__EMSCRIPTEN__)
360    Mutex mutex { };
361 #endif
362 };