ecere/gfx/Surface; drivers: Font outline support
[sdk] / ecere / src / gfx / drivers / CocoaOpenGLDisplayDriver.ec
1 #define USEPBUFFER
2
3 namespace gfx::drivers;
4
5 #include <OpenGl/gl.h>
6 #undef __BLOCKS__
7 #include <stdlib.h>
8
9 import "CocoaInterface.ec"
10 #include "CocoaEcereBridge.h"
11
12 import "Display"
13 import "Window"
14
15 #define glLoadMatrix glLoadMatrixd
16 #define glMultMatrix glMultMatrixd
17 #define glGetMatrix  glGetDoublev
18 #define glTranslate glTranslated
19 #define glScale glScaled
20
21 #define GL_ARRAY_BUFFER_ARB            0x8892
22 #define GL_ELEMENT_ARRAY_BUFFER_ARB    0x8893
23 #define GL_STATIC_DRAW_ARB             0x88E4
24 #define GL_LIGHT_MODEL_COLOR_CONTROL   0x81F8
25 #define GL_SEPARATE_SPECULAR_COLOR     0x81FA
26
27 #define GL_MULTISAMPLE_ARB             0x809D
28
29 //static int displayWidth, displayHeight;
30
31 #define GL_CLAMP_TO_EDGE 0x812F
32
33 class DisplayData : struct
34 {
35    ColorAlpha * flippingBuffer;
36    int flipBufH, flipBufW;
37    bool depthWrite;
38    int x, y;
39    uint stride;
40    byte * picture;
41 };
42
43 class SystemData : struct
44 {
45    bool loadingFont;
46 };
47
48 class SurfaceData : struct
49 {
50    Font font;
51    bool opaqueText;
52    int  xOffset;
53    bool writingText;
54    bool writingOutline;
55
56    float foreground[4], background[4], bitmapMult[4];
57 };
58
59 class MeshData : struct
60 {
61    uint vertices;
62    uint normals;
63    uint texCoords;
64    uint texCoords2;
65    uint colors;
66 };
67
68 class IndexData : struct
69 {
70    uint16 *indices;
71    uint buffer;
72    uint nIndices;
73 };
74
75 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
76 static int primitiveTypes[RenderPrimitiveType] =
77 {
78    GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_LINE_STRIP
79 };
80 #endif
81
82 int current;
83 void *previous;
84
85 void CocoaGlAssert()
86 {
87     GLenum error = glGetError();
88
89     if(error) {
90         printf("**** glGetError():%i ****\n", error);
91         exit(1);
92     }
93 }
94
95 class CocoaOpenGLDisplayDriver : DisplayDriver
96 {
97    class_property(name) = "CocoaOpenGL";
98
99    bool LockSystem(DisplaySystem displaySystem)
100    {
101       printf("CocoaOpenGLDisplayDriver:LockSystem STUB! %s:%i\n", __FILE__, __LINE__);
102       return true;
103    }
104
105    void UnlockSystem(DisplaySystem displaySystem)
106    {
107       printf("CocoaOpenGLDisplayDriver:UnlockSystem STUB! %s:%i\n", __FILE__, __LINE__);
108    }
109
110    bool Lock(Display display)
111    {
112       printf("CocoaOpenGLDisplayDriver:Lock %s:%i\n", __FILE__, __LINE__);
113       return CocoaLock(display.window);
114    }
115
116    void Unlock(Display display)
117    {
118       printf("CocoaOpenGLDisplayDriver:Unlock %s:%i\n", __FILE__, __LINE__);
119       CocoaUnlock(display.window);
120    }
121
122    void DestroyDisplay(Display display)
123    {
124       printf("CocoaOpenGLDisplayDriver:DestroyDisplay STUB! %s:%i\n", __FILE__, __LINE__);
125    }
126
127    bool CreateDisplaySystem(DisplaySystem displaySystem)
128    {
129       bool result = true;
130
131       SystemData system = SystemData { };
132       displaySystem.driverData = system;
133
134       printf("CocoaOpenGLDisplayDriver:CreateDisplaySystem %s:%i\n", __FILE__, __LINE__);
135       return result;
136    }
137
138    void DestroyDisplaySystem(DisplaySystem displaySystem)
139    {
140       printf("CocoaOpenGLDisplayDriver:DestroyDisplaySystem STUB! %s:%i\n", __FILE__, __LINE__);
141    }
142
143    bool CreateDisplay(Display display)
144    {
145       bool result = true;
146
147       DisplayData displayData = display.driverData;
148       //SystemData systemData = display.displaySystem.driverData;
149
150       displayData = display.driverData = DisplayData { };
151
152       CocoaOpenGLMakeCurrentContext(display.window);
153
154       CocoaGlAssert();
155       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
156       CocoaGlAssert();
157       glEnable(GL_BLEND);
158       CocoaGlAssert();
159
160       glMatrixMode(GL_MODELVIEW);
161       CocoaGlAssert();
162       glScalef(1.0f, 1.0f, -1.0f);
163       CocoaGlAssert();
164       glMatrixMode(GL_PROJECTION);
165       CocoaGlAssert();
166       glShadeModel(GL_FLAT);
167       CocoaGlAssert();
168
169       glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
170       CocoaGlAssert();
171       glFogi(GL_FOG_MODE, GL_EXP);
172       CocoaGlAssert();
173       glFogf(GL_FOG_DENSITY, 0);
174       CocoaGlAssert();
175       glEnable(GL_NORMALIZE);
176       CocoaGlAssert();
177       glDepthFunc(GL_LESS);
178       CocoaGlAssert();
179       glClearDepth(1.0);
180       CocoaGlAssert();
181       glDisable(GL_MULTISAMPLE_ARB);
182       CocoaGlAssert();
183
184 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
185       display.ambient = Color { 50,50,50 };
186 #endif
187
188       printf("CocoaOpenGLDisplayDriver:CreateDisplay %p %s:%i\n", display.window, __FILE__, __LINE__);
189       return result;
190    }
191
192    bool DisplaySize(Display display, int width, int height)
193    {
194       bool result = true;
195
196       DisplayData displayData = display.driverData;
197       //SystemData systemData = display.displaySystem.driverData;
198
199       printf("CocoaOpenGLDisplayDriver:DisplaySize(%i,%i) %s:%i\n", width, height, __FILE__, __LINE__);
200
201       CocoaOpenGLMakeCurrentContext(display.window);
202
203       glViewport(0,0,width,height);
204       CocoaGlAssert();
205       glLoadIdentity();
206       CocoaGlAssert();
207       glOrtho(0,width,height,0,0.0,1.0);
208       CocoaGlAssert();
209       display.width = width;
210       display.height = height;
211
212       if(!displayData.flippingBuffer || displayData.flipBufW < width || displayData.flipBufH < height)
213       {
214          displayData.flipBufW = width;
215          displayData.flipBufH = height;
216          displayData.flippingBuffer = renew displayData.flippingBuffer ColorAlpha [width * height];
217       }
218       if(displayData.flippingBuffer)
219          result = true;
220
221       return result;
222    }
223
224    void DisplayPosition(Display display, int x, int y)
225    {
226       DisplayData displayData = display.driverData;
227
228       printf("CocoaOpenGLDisplayDriver:DisplayPosition(%i,%i) %s:%i\n", x, y, __FILE__, __LINE__);
229
230       displayData.x = x;
231       displayData.y = y;
232       printf("glGetError():%i\n", glGetError());
233    }
234
235    void SetPalette(Display display, ColorAlpha * palette, bool colorMatch)
236    {
237       printf("CocoaOpenGLDisplayDriver:SetPalette STUB! %s:%i\n", __FILE__, __LINE__);
238    }
239
240    void RestorePalette(Display display)
241    {
242       printf("CocoaOpenGLDisplayDriver:RestorePalette STUB! %s:%i\n", __FILE__, __LINE__);
243    }
244
245    void StartUpdate(Display display)
246    {
247       printf("CocoaOpenGLDisplayDriver:StartUpdate STUB! %s:%i\n", __FILE__, __LINE__);
248    }
249
250    void EndUpdate(Display display)
251    {
252       printf("CocoaOpenGLDisplayDriver:EndUpdate STUB! %s:%i\n", __FILE__, __LINE__);
253    }
254
255    void Scroll(Display display, Box scroll, int x, int y, Extent dirty)
256    {
257       printf("CocoaOpenGLDisplayDriver:Scroll STUB! %s:%i\n", __FILE__, __LINE__);
258    }
259
260    void Update(Display display, Box updateBox)
261    {
262       //CocoaOpenGLUpdate(display.window);
263       printf("CocoaOpenGLDisplayDriver:Update %s:%i\n", __FILE__, __LINE__);
264    }
265
266    void FreeBitmap(DisplaySystem displaySystem, Bitmap bitmap)
267    {
268       uint glBitmap = (uint)(uintptr)bitmap.driverData;
269       glDeleteTextures(1, &glBitmap);
270       bitmap.driverData = 0;
271
272       bitmap.driver = class(LFBDisplayDriver);
273
274       printf("CocoaOpenGLDisplayDriver:FreeBitmap %s:%i\n", __FILE__, __LINE__);
275    }
276
277    bool AllocateBitmap(DisplaySystem displaySystem, Bitmap bitmap, int width, int height, int stride, PixelFormat format, bool allocatePalette)
278    {
279       bool result = false;
280       Bitmap mipMap { };
281       uint glBitmap = 0;
282
283       uint w = pow2i(Min(width, 1024)), h = pow2i(Min(height, 1024));
284
285       printf("CocoaOpenGLDisplayDriver:AllocateBitmap %s:%i\n", __FILE__, __LINE__);
286
287       CocoaGlAssert();
288       glGenTextures(1, &glBitmap);
289       CocoaGlAssert();
290       glBindTexture(GL_TEXTURE_2D, glBitmap);
291
292       CocoaGlAssert();
293       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
294
295       CocoaGlAssert();
296       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
297       CocoaGlAssert();
298       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
299
300       CocoaGlAssert();
301       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
302       CocoaGlAssert();
303       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
304
305       CocoaGlAssert();
306       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
307
308       mipMap.Allocate(null, w, h, w, pixelFormatRGBA, false);
309
310       CocoaGlAssert();
311       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
312       delete mipMap;
313
314       bitmap.driverData = (void *)(uintptr)glBitmap;
315       bitmap.driver = displaySystem.driver;
316       bitmap.width = w;
317       bitmap.height = h;
318
319       result = true;
320
321       return result;
322    }
323
324    bool MakeDDBitmap(DisplaySystem displaySystem, Bitmap bitmap, bool mipMaps)
325    {
326       bool result = false;
327       SystemData systemData = displaySystem.driverData;
328
329       // Pre process the bitmap... First make it 32 bit
330       if(bitmap.Convert(null, pixelFormat888, null))
331       {
332          int c, level;
333          uint w = pow2i(Min(bitmap.width, 1024)), h = pow2i(Min(bitmap.height, 1024));
334          uint glBitmap = 0;
335
336          // Switch ARGB to RGBA
337          //if(bitmap.format != pixelFormatRGBA)
338          {
339             for(c=0; c<bitmap.size; c++)
340             {
341                // TODO:
342                ColorAlpha color = ((ColorAlpha *)bitmap.picture)[c];
343                ((ColorRGBA *)bitmap.picture)[c] = ColorRGBA { color.color.r, color.color.g, color.color.b, color.a };
344             }
345          }
346          bitmap.pixelFormat = pixelFormat888;
347
348       CocoaGlAssert();
349          glGenTextures(1, &glBitmap);
350       CocoaGlAssert();
351          if(glBitmap == 0)
352          {
353             //int error = glGetError();
354             return false;
355             //Print("");
356          }
357
358       CocoaGlAssert();
359          glBindTexture(GL_TEXTURE_2D, glBitmap);
360       CocoaGlAssert();
361          glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
362       CocoaGlAssert();
363
364          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
365       CocoaGlAssert();
366          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mipMaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
367       CocoaGlAssert();
368
369          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
370       CocoaGlAssert();
371          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
372       CocoaGlAssert();
373
374          glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
375       CocoaGlAssert();
376
377          result = true;
378
379          for(level = 0; result && (w > 1 || h > 1); level++, w >>= 1, h >>= 1)
380          {
381             Bitmap mipMap;
382             if(bitmap.width != w || bitmap.height != h)
383             {
384                mipMap = Bitmap { };
385                if(mipMap.Allocate(null, w, h, w, bitmap.pixelFormat, false))
386                {
387                   Surface mipSurface = mipMap.GetSurface(0,0,null);
388                   mipSurface.Filter(bitmap, 0,0,0,0, w, h, bitmap.width, bitmap.height);
389                   delete mipSurface;
390                }
391                else
392                {
393                   result = false;
394                   delete mipMap;
395                }
396             }
397             else
398                mipMap = bitmap;
399
400             if(result)
401             {
402                int error;
403                glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipMap.picture);
404       CocoaGlAssert();
405                if((error = glGetError()))
406                {
407                   result = false;
408                }
409             }
410             if(mipMap != bitmap)
411                delete mipMap;
412             if(!mipMaps) break;
413          }
414
415          if(!bitmap.keepData)
416             bitmap.driver.FreeBitmap(bitmap.displaySystem, bitmap);
417          bitmap.driverData = (void *)(uintptr)glBitmap;
418          bitmap.driver = displaySystem.driver;
419
420          if(!result)
421             FreeBitmap(displaySystem, bitmap);
422          else if(systemData.loadingFont)
423          {
424             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
425       CocoaGlAssert();
426             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
427       CocoaGlAssert();
428             systemData.loadingFont = false;
429          }
430       }
431
432       printf("CocoaOpenGLDisplayDriver:MakeDDBitmap %i %s:%i\n", result, __FILE__, __LINE__);
433       return result;
434    }
435
436    void ReleaseSurface(Display display, Surface surface)
437    {
438       printf("CocoaOpenGLDisplayDriver:ReleaseSurface %s:%i\n", __FILE__, __LINE__);
439
440       glDisable(GL_SCISSOR_TEST);
441       CocoaGlAssert();
442       delete surface.driverData;
443       surface.driverData = null;
444    }
445
446    bool GetBitmapSurface(DisplaySystem displaySystem, Surface surface, Bitmap bitmap, int x, int y, Box clip)
447    {
448       printf("CocoaOpenGLDisplayDriver:GetBitmapSurface STUB! %s:%i\n", __FILE__, __LINE__);
449       return false;
450    }
451
452    bool GetSurface(Display display, Surface surface, int x,int y, Box clip)
453    {
454       bool result = true;
455
456       SurfaceData surfaceData = SurfaceData { };
457       surface.driverData = surfaceData;
458
459       printf("CocoaOpenGLDisplayDriver:GetSurface %p %s:%i\n", surfaceData, __FILE__, __LINE__);
460
461       if(surfaceData)
462       {
463       CocoaGlAssert();
464             glViewport(0,0,display.width,display.height);
465       CocoaGlAssert();
466             glLoadIdentity();
467       CocoaGlAssert();
468             printf("display:%i, %i\n", display.width, display.height);
469             glOrtho(0, display.width, display.height, 0, 0.0f, 1.0f);
470       CocoaGlAssert();
471
472          surface.offset.x = x;
473          surface.offset.y = y;
474          surface.unclippedBox = surface.box = clip;
475          surfaceData.bitmapMult[0] = 1;
476          surfaceData.bitmapMult[1] = 1;
477          surfaceData.bitmapMult[2] = 1;
478          surfaceData.bitmapMult[3] = 1;
479
480          glEnable(GL_SCISSOR_TEST);
481       CocoaGlAssert();
482          glScissor(
483             x+clip.left,
484             (display.height) -(y+clip.bottom)-1,
485             clip.right-clip.left+1,
486             clip.bottom-clip.top+1);
487       CocoaGlAssert();
488          result = true;
489       }
490
491       return result;
492    }
493
494    void Clip(Display display, Surface surface, Box clip)
495    {
496       Box box;
497
498       printf("CocoaOpenGLDisplayDriver:Clip STUB! %s:%i\n", __FILE__, __LINE__);
499
500       if(clip != null)
501       {
502          box = clip;
503          box.Clip(surface.unclippedBox);
504          surface.box = box;
505       }
506       else
507       {
508          box = surface.box = surface.unclippedBox;
509       }
510
511       box.left += surface.offset.x;
512       box.top  += surface.offset.y;
513       box.right+= surface.offset.x;
514       box.bottom += surface.offset.y;
515
516       glScissor(
517          box.left,display.height - box.bottom - 1,
518          box.right-box.left+1, box.bottom-box.top+1);
519    }
520
521    bool GrabScreen(Display display, Bitmap bitmap, int x, int y, unsigned int w, unsigned int h)
522    {
523       bool result = false;
524       printf("CocoaOpenGLDisplayDriver:GrabScreen STUB! %s:%i\n", __FILE__, __LINE__);
525       return result;
526    }
527
528    void SetForeground(Display display, Surface surface, ColorAlpha color)
529    {
530       SurfaceData surfaceData = surface.driverData;
531
532       printf("CocoaOpenGLDisplayDriver:SetForeground(%i,%i,%i,%i) %s:%i\n", color.color.r, color.color.g, color.color.b, color.a, __FILE__, __LINE__);
533
534       surfaceData.foreground[0] = color.color.r/255.0f;
535       surfaceData.foreground[1] = color.color.g/255.0f;
536       surfaceData.foreground[2] = color.color.b/255.0f;
537       surfaceData.foreground[3] = color.a/255.0f;
538    }
539
540    void SetBackground(Display display, Surface surface, ColorAlpha color)
541    {
542       SurfaceData surfaceData = surface.driverData;
543
544       printf("CocoaOpenGLDisplayDriver:SetBackground(%i,%i,%i,%i) %s:%i\n", color.color.r, color.color.g, color.color.b, color.a, __FILE__, __LINE__);
545
546       surfaceData.background[0] = color.color.r/255.0f;
547       surfaceData.background[1] = color.color.g/255.0f;
548       surfaceData.background[2] = color.color.b/255.0f;
549       surfaceData.background[3] = color.a/255.0f;
550    }
551
552    void SetBlitTint(Display display, Surface surface, ColorAlpha color)
553    {
554       SurfaceData surfaceData = surface.driverData;
555
556       printf("CocoaOpenGLDisplayDriver:SetBlitTint(%i,%i,%i,%i) %s:%i\n", color.color.r, color.color.g, color.color.b, color.a, __FILE__, __LINE__);
557
558       surfaceData.bitmapMult[0] = color.color.r/255.0f;
559       surfaceData.bitmapMult[1] = color.color.g/255.0f;
560       surfaceData.bitmapMult[2] = color.color.b/255.0f;
561       surfaceData.bitmapMult[3] = color.a/255.0f;
562    }
563
564
565    ColorAlpha GetPixel(Display display, Surface surface,int x,int y)
566    {
567       printf("CocoaOpenGLDisplayDriver:GetPixel STUB! %s:%i\n", __FILE__, __LINE__);
568       return 0;
569    }
570
571    void PutPixel(Display display, Surface surface,int x,int y)
572    {
573       printf("CocoaOpenGLDisplayDriver:PutPixel %s:%i\n", __FILE__, __LINE__);
574
575       glBegin(GL_POINTS);
576       CocoaGlAssert();
577       glVertex2f(x+surface.offset.x + 0.5f, y+surface.offset.y + 0.5f);
578       glEnd();
579       CocoaGlAssert();
580    }
581
582    void DrawLine(Display display, Surface surface, int x1, int y1, int x2, int y2)
583    {
584       SurfaceData surfaceData = surface.driverData;
585
586       printf("CocoaOpenGLDisplayDriver:DrawLine %s:%i\n", __FILE__, __LINE__);
587       printf("--DrawLine(x1:%i, y1:%i, x2:%i, y2:%i)\n", x1, y1, x2, y2);
588
589       glColor4fv(surfaceData.foreground);
590       glBegin(GL_LINES);
591
592       glVertex2f(x1+surface.offset.x + 0.5f, y1+surface.offset.y + 0.5f);
593       glVertex2f(x2+surface.offset.x + 0.5f, y2+surface.offset.y + 0.5f);
594
595       glEnd();
596       CocoaGlAssert();
597    }
598
599    void Rectangle(Display display, Surface surface,int x1,int y1,int x2,int y2)
600    {
601       printf("CocoaOpenGLDisplayDriver:Rectangle %s:%i\n", __FILE__, __LINE__);
602       printf("--Rectangle(x1:%i, y1:%i, x2:%i, y2:%i)\n", x1, y1, x2, y2);
603       glBegin(GL_LINE_LOOP);
604
605       glVertex2f(x1+surface.offset.x + 0.5f, y1+surface.offset.y + 0.5f);
606       glVertex2f(x1+surface.offset.x + 0.5f, y2+surface.offset.y + 0.5f);
607       glVertex2f(x2+surface.offset.x + 0.5f, y2+surface.offset.y + 0.5f);
608       glVertex2f(x2+surface.offset.x + 0.5f, y1+surface.offset.y + 0.5f);
609
610       glEnd();
611       CocoaGlAssert();
612    }
613
614    void Area(Display display, Surface surface,int x1,int y1,int x2,int y2)
615    {
616       SurfaceData surfaceData = surface.driverData;
617
618       printf("CocoaOpenGLDisplayDriver:Area %s:%i\n", __FILE__, __LINE__);
619
620       CocoaGlAssert();
621       glColor4fv(surfaceData.background);
622
623       glRecti(x1+surface.offset.x, y1+surface.offset.y,
624               x2+surface.offset.x + 1, y2+surface.offset.y + 1);
625       CocoaGlAssert();
626    }
627
628    void Clear(Display display, Surface surface, ClearType type)
629    {
630       DisplayData displayData = display.driverData;
631       SurfaceData surfaceData = surface.driverData;
632
633       if(type != depthBuffer)
634       {
635          glClearColor(surfaceData.background[0], surfaceData.background[1], surfaceData.background[2], surfaceData.background[3]);
636       CocoaGlAssert();
637       }
638       if(type != colorBuffer && !displayData.depthWrite)
639       {
640          glDepthMask((byte)bool::true);
641       CocoaGlAssert();
642       }
643       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
644               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
645       CocoaGlAssert();
646
647       if(type != colorBuffer && !displayData.depthWrite)
648       {
649          glDepthMask((byte)bool::false);
650       CocoaGlAssert();
651       }
652       if(type != depthBuffer)
653       {
654          glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
655       CocoaGlAssert();
656       }
657       if(type != colorBuffer)
658       {
659          glDepthMask((byte)bool::true);
660       CocoaGlAssert();
661       }
662
663       glClear(((type != depthBuffer) ? GL_COLOR_BUFFER_BIT : 0) |
664               ((type != colorBuffer) ? GL_DEPTH_BUFFER_BIT : 0));
665       CocoaGlAssert();
666
667       if(type != colorBuffer)
668       {
669          glDepthMask((byte)bool::false);
670       CocoaGlAssert();
671       }
672       printf("CocoaOpenGLDisplayDriver:Clear %s:%i\n", __FILE__, __LINE__);
673    }
674
675    bool ConvertBitmap(DisplaySystem displaySystem, Bitmap bitmap, PixelFormat format, ColorAlpha * palette)
676    {
677       bool result = false;
678
679       printf("CocoaOpenGLDisplayDriver:ConvertBitmap %s:%i\n", __FILE__, __LINE__);
680
681       return result;
682    }
683
684    void Blit(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
685    {
686       printf("CocoaOpenGLDisplayDriver:Blit %s:%i\n", __FILE__, __LINE__);
687       printf("--BLIT(dx:%i, dy:%i, sx:%i, sy:%i, w:%i, h:%i)\n", dx, dy, sx, sy, w, h);
688
689       glEnable(GL_TEXTURE_2D);
690       glBindTexture(GL_TEXTURE_2D, (uint)bitmap.driverData);
691       glBegin(GL_QUADS);
692
693       if(h < 0)
694       {
695          glTexCoord2f((float)sx/ bitmap.width, (float)(sy-h)/ bitmap.height);
696          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
697          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy-h)/ bitmap.height);
698          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
699          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
700          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
701          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
702          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
703       }
704       else
705       {
706          glTexCoord2f((float)sx / bitmap.width, (float)sy/ bitmap.height);
707          glVertex2f((float)dx+surface.offset.x, (float)dy+surface.offset.y);
708          glTexCoord2f((float)(sx+w)/ bitmap.width, (float)sy/ bitmap.height);
709          glVertex2f((float)dx+w+surface.offset.x, (float)dy+surface.offset.y);
710          glTexCoord2f((float)(sx+w) / bitmap.width, (float)(sy+h)/ bitmap.height);
711          glVertex2f((float)dx+w+surface.offset.x, (float)dy+h+surface.offset.y);
712          glTexCoord2f((float)sx/ bitmap.width, (float)(sy+h)/ bitmap.height);
713          glVertex2f((float)dx+surface.offset.x, (float)dy+h+surface.offset.y);
714       }
715       glEnd();
716       CocoaGlAssert();
717    }
718
719    void Stretch(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
720    {
721       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
722       glEnable(GL_TEXTURE_2D);
723       CocoaGlAssert();
724       glBindTexture(GL_TEXTURE_2D, (uint)bitmap.driverData);
725       CocoaGlAssert();
726
727       glBegin(GL_QUADS);
728       CocoaGlAssert();
729
730       if(h < 0)
731       {
732          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
733       CocoaGlAssert();
734          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
735       CocoaGlAssert();
736
737          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
738       CocoaGlAssert();
739          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
740       CocoaGlAssert();
741
742          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
743       CocoaGlAssert();
744          glVertex2i(dx+w+surface.offset.x, dy-h+surface.offset.y);
745       CocoaGlAssert();
746
747          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
748       CocoaGlAssert();
749          glVertex2i(dx+surface.offset.x, dy-h+surface.offset.y);
750       CocoaGlAssert();
751       }
752       else
753       {
754          glTexCoord2f((float)(sx) / bitmap.width, (float)(sy)/ bitmap.height);
755       CocoaGlAssert();
756          glVertex2i(dx+surface.offset.x, dy+surface.offset.y);
757       CocoaGlAssert();
758
759          glTexCoord2f((float)(sx+sw)/ bitmap.width, (float)(sy)/ bitmap.height);
760       CocoaGlAssert();
761          glVertex2i(dx+w+surface.offset.x, dy+surface.offset.y);
762       CocoaGlAssert();
763
764          glTexCoord2f((float)(sx+sw) / bitmap.width, (float)(sy+sh)/ bitmap.height);
765       CocoaGlAssert();
766          glVertex2i(dx+w+surface.offset.x, dy+h+surface.offset.y);
767       CocoaGlAssert();
768
769          glTexCoord2f((float)(sx)/ bitmap.width, (float)(sy+sh)/ bitmap.height);
770       CocoaGlAssert();
771          glVertex2i(dx+surface.offset.x, dy+h+surface.offset.y);
772       CocoaGlAssert();
773       }
774
775       glEnd();
776       CocoaGlAssert();
777
778       glDisable(GL_TEXTURE_2D);
779       CocoaGlAssert();
780    }
781
782    void Filter(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
783    {
784       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
785       Stretch(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
786    }
787
788    void StretchDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
789    {
790       float s2dw,s2dh,d2sw,d2sh;
791       bool flipX = false, flipY = false;
792
793       printf("CocoaOpenGLDisplayDriver: %s:%i\n", __FILE__, __LINE__);
794       if(Sgn(w) != Sgn(sw))
795       {
796          w = Abs(w);
797          sw = Abs(sw);
798          flipX = true;
799       }
800       if(Sgn(h) != Sgn(sh))
801       {
802          h = Abs(h);
803          sh = Abs(sh);
804          flipY = true;
805       }
806
807       s2dw=(float)w / sw;
808       s2dh=(float)h / sh;
809       d2sw=(float)sw / w;
810       d2sh=(float)sh / h;
811
812       //Clip against the edges of the source
813       if(sx<0)
814       {
815          dx+=(int)((0-sx) * s2dw);
816          w-=(int)((0-sx) * s2dw);
817          sw-=0-sx;
818          sx=0;
819       }
820       if(sy<0)
821       {
822          dy+=(int)((0-sy) * s2dh);
823          h-=(int)((0-sy) * s2dh);
824
825          sh-=0-sy;
826          sy=0;
827       }
828       if(sx+sw>bitmap.width-1)
829       {
830          w-=(int)((sx+sw-(bitmap.width-1)-1)*s2dw);
831          sw-=sx+sw-(bitmap.width-1)-1;
832       }
833       if(sy+sh>(bitmap.height-1))
834       {
835          h-=(int)((sy+sh-(bitmap.height-1)-1)*s2dh);
836          sh-=sy+sh-(bitmap.height-1)-1;
837       }
838       //Clip against the edges of the surfaceination
839       if(dx<surface.box.left)
840       {
841          //if(!flip)
842          sx+=(int)((surface.box.left-dx)*d2sw);
843          sw-=(int)((surface.box.left-dx)*d2sw);
844          w-=surface.box.left-dx;
845          dx=surface.box.left;
846       }
847       if(dy<surface.box.top)
848       {
849          sy+=(int)((surface.box.top-dy)*d2sh);
850          sh-=(int)((surface.box.top-dy)*d2sh);
851          h-=surface.box.top-dy;
852          dy=surface.box.top;
853       }
854       if(dx+w>surface.box.right)
855       {
856          //if(flip) sx+=(int)((dx+w-surface.box.right-1)*d2sw);
857          sw-=(int)((dx+w-surface.box.right-1)*d2sw);
858          w-=dx+w-surface.box.right-1;
859       }
860       if(dy+h>surface.box.bottom)
861       {
862          sh-=(int)((dy+h-surface.box.bottom-1)*d2sh);
863          h-=dy+h-surface.box.bottom-1;
864       }
865       if((w<=0)||(h<=0)||(sw<=0)||(sh<=0)) return;
866
867       dx += surface.offset.x;
868       dy += surface.offset.y;
869
870       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
871       {
872          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
873       CocoaGlAssert();
874          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
875       CocoaGlAssert();
876          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
877       CocoaGlAssert();
878          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
879       CocoaGlAssert();
880          glRasterPos2d(dx,dy);
881       CocoaGlAssert();
882          //glPixelZoom(flipX ? -s2dw : s2dw, flipY ? s2dh : -s2dh);
883       CocoaGlAssert();
884          glPixelZoom(s2dw, -s2dh);
885       CocoaGlAssert();
886          glDrawPixels(sw,sh,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
887       CocoaGlAssert();
888          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
889       CocoaGlAssert();
890          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
891       CocoaGlAssert();
892       }
893    }
894
895    void BlitDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h)
896    {
897       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
898       //Clip against the edges of the source
899       if(sx<0)
900       {
901          dx+=-sx;
902          w-=-sx;
903          sx=0;
904       }
905       if(sy<0)
906       {
907          dy+=0-sy;
908          h-=0-sy;
909          sy=0;
910       }
911       if(sx+w>bitmap.width-1)
912          w-=sx+w-(bitmap.width-1)-1;
913       if(sy+h>bitmap.height-1)
914          h-=sy+h-(bitmap.height-1)-1;
915       //Clip against the edges of the surfaceination
916       if(dx<surface.box.left)
917       {
918          //if(!flip)
919          sx+=surface.box.left-dx;
920          w-=surface.box.left-dx;
921          dx=surface.box.left;
922       }
923       if(dy<surface.box.top)
924       {
925          sy+=surface.box.top-dy;
926          h-=surface.box.top-dy;
927          dy=surface.box.top;
928       }
929       if(dx+w>surface.box.right)
930       {
931          //if(flip) sx+=dx+w-surface.box.right-1;
932          w-=dx+w-surface.box.right-1;
933       }
934       if(dy+h>surface.box.bottom)
935          h-=dy+h-surface.box.bottom-1;
936       if((w<=0)||(h<=0))
937          return;
938
939       dx += surface.offset.x;
940       dy += surface.offset.y;
941
942       if(bitmap.pixelFormat == pixelFormat888 && !bitmap.paletteShades)
943       {
944          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
945       CocoaGlAssert();
946          glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.stride);
947       CocoaGlAssert();
948          glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
949       CocoaGlAssert();
950          glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
951       CocoaGlAssert();
952          glRasterPos2d(dx,dy);
953       CocoaGlAssert();
954          glPixelZoom(1,-1);
955       CocoaGlAssert();
956          glDrawPixels(w,h,GL_BGRA_EXT,GL_UNSIGNED_BYTE, bitmap.picture);
957       CocoaGlAssert();
958          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
959       CocoaGlAssert();
960          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
961       CocoaGlAssert();
962       }
963    }
964
965    void FilterDI(Display display, Surface surface, Bitmap bitmap, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
966    {
967       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
968       StretchDI(display, surface, bitmap, dx, dy, sx, sy, w, h, sw, sh);
969    }
970
971    void UnloadFont(DisplaySystem displaySystem, Font font)
972    {
973       printf("CocoaOpenGLDisplayDriver:UnloadFont %s:%i\n", __FILE__, __LINE__);
974       LFBDisplayDriver::UnloadFont(displaySystem, font);
975    }
976
977    Font LoadFont(DisplaySystem displaySystem, const char * faceName, float size, FontFlags flags)
978    {
979       Font font = LFBDisplayDriver::LoadFont(displaySystem, faceName, size, flags);
980
981       printf("CocoaOpenGLDisplayDriver:LoadFont(%s):%p %s:%i\n", faceName, font, __FILE__, __LINE__);
982
983       return font;
984    }
985
986    void FontExtent(DisplaySystem displaySystem, Font font, const char * text, int len, int * width, int * height)
987    {
988       printf("CocoaOpenGLDisplayDriver:FontExtent() %s:%i\n", __FILE__, __LINE__);
989       LFBDisplayDriver::FontExtent(displaySystem, font, text, len, width, height);
990    }
991
992    void WriteText(Display display, Surface surface, int x, int y, const char * text, int len)
993    {
994       SurfaceData surfaceData = surface.driverData;
995       SystemData systemData = display.displaySystem.driverData;
996
997       printf("CocoaOpenGLDisplayDriver:WriteText %s:%i\n", __FILE__, __LINE__);
998
999       systemData.loadingFont = true;
1000
1001       if(surface.textOpacity)
1002       {
1003          int w, h;
1004          FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
1005          Area(display, surface,x,y,x+w-1,y+h-1);
1006       }
1007
1008       surfaceData.writingText = true;
1009
1010       glEnable(GL_TEXTURE_2D);
1011       CocoaGlAssert();
1012       glColor4fv(surfaceData.foreground);
1013       CocoaGlAssert();
1014
1015       LFBDisplayDriver::WriteText(display, surface, x, y, text, len);
1016       surfaceData.writingText = false;
1017       systemData.loadingFont = false;
1018
1019       glDisable(GL_TEXTURE_2D);
1020       CocoaGlAssert();
1021    }
1022
1023    void TextFont(Display display, Surface surface, Font font)
1024    {
1025       LFBDisplayDriver::TextFont(display, surface, font);
1026       printf("CocoaOpenGLDisplayDriver:TextFont %s:%i\n", __FILE__, __LINE__);
1027    }
1028
1029    void TextOpacity(Display display, Surface surface, bool opaque)
1030    {
1031       SurfaceData surfaceData = surface.driverData;
1032       surfaceData.opaqueText = opaque;
1033       printf("CocoaOpenGLDisplayDriver:TextOpacity(%i) %s:%i\n", opaque, __FILE__, __LINE__);
1034    }
1035
1036    void TextExtent(Display display, Surface surface, const char * text, int len, int * width, int * height)
1037    {
1038       SurfaceData surfaceData = surface.driverData;
1039       SystemData systemData = display.displaySystem.driverData;
1040       systemData.loadingFont = true;
1041       FontExtent(display.displaySystem, surfaceData.font, text, len, width, height);
1042       systemData.loadingFont = false;
1043
1044       printf("CocoaOpenGLDisplayDriver:TextExtent STUB! %s:%i\n", __FILE__, __LINE__);
1045    }
1046
1047    void DrawingChar(Display display, Surface surface, char character)
1048    {
1049       printf("CocoaOpenGLDisplayDriver:DrawingChar STUB! %s:%i\n", __FILE__, __LINE__);
1050
1051    }
1052
1053    void LineStipple(Display display, Surface surface, uint32 stipple)
1054    {
1055       printf("CocoaOpenGLDisplayDriver:LineStipple %s:%i\n", __FILE__, __LINE__);
1056       if(stipple)
1057       {
1058          glLineStipple(1, (uint16)stipple);
1059       CocoaGlAssert();
1060          glEnable(GL_LINE_STIPPLE);
1061       CocoaGlAssert();
1062       }
1063       else
1064       {
1065          glDisable(GL_LINE_STIPPLE);
1066       CocoaGlAssert();
1067       }
1068       printf("glGetError():%i\n", glGetError());
1069    }
1070
1071 #if !defined(ECERE_NO3D) && !defined(ECERE_VANILLA)
1072    void SetRenderState(Display display, RenderState state, uint value)
1073    {
1074       printf("CocoaOpenGLDisplayDriver:SetRenderState STUB! %s:%i\n", __FILE__, __LINE__);
1075       switch(state)
1076       {
1077          case antiAlias:
1078             if(value)
1079                glEnable(GL_MULTISAMPLE_ARB);
1080             else
1081                glDisable(GL_MULTISAMPLE_ARB);
1082       CocoaGlAssert();
1083             break;
1084          case fillMode:
1085             glPolygonMode(GL_FRONT_AND_BACK, ((FillModeValue)value == solid) ? GL_FILL : GL_LINE);
1086       CocoaGlAssert();
1087             break;
1088          case depthTest:
1089             if(value) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
1090       CocoaGlAssert();
1091             break;
1092          case depthWrite:
1093             if(value) glDepthMask((byte)bool::true); else glDepthMask((byte)bool::false);
1094       CocoaGlAssert();
1095             break;
1096          case fogColor:
1097          {
1098             float color[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
1099             glFogfv(GL_FOG_COLOR, (float *)&color);
1100       CocoaGlAssert();
1101             break;
1102          }
1103          case fogDensity:
1104             glFogf(GL_FOG_DENSITY, *(float *)(void *)&value);
1105       CocoaGlAssert();
1106             break;
1107          case blend:
1108             if(value) glEnable(GL_BLEND); else glDisable(GL_BLEND);
1109       CocoaGlAssert();
1110             break;
1111          case ambient:
1112          {
1113             float ambient[4] = { ((Color)value).r/255.0f, ((Color)value).g/255.0f, ((Color)value).b/255.0f, 1.0f };
1114             glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
1115       CocoaGlAssert();
1116             break;
1117          }
1118          case alphaWrite:
1119          {
1120             if(value) glColorMask(1,1,1,1); else glColorMask(1,1,1,0);
1121       CocoaGlAssert();
1122             break;
1123          }
1124          case vSync:
1125          {
1126             break;
1127          }
1128       }
1129    }
1130
1131    void SetLight(Display display, int id, Light light)
1132    {
1133       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1134       if(light != null)
1135       {
1136          Object lightObject = light.lightObject;
1137          float position[4] = { 0, 0, 0, 0 };
1138          float color[4] = { 0, 0, 0, 1 };
1139
1140          glEnable(GL_LIGHT0 + id);
1141       CocoaGlAssert();
1142
1143          if(!light.multiplier) light.multiplier = 1.0f;
1144
1145          color[0] = light.diffuse.r * light.multiplier;
1146          color[1] = light.diffuse.g * light.multiplier;
1147          color[2] = light.diffuse.b * light.multiplier;
1148          glLightfv(GL_LIGHT0 + id, GL_DIFFUSE, color);
1149
1150          color[0] = light.ambient.r * light.multiplier;
1151          color[1] = light.ambient.g * light.multiplier;
1152          color[2] = light.ambient.b * light.multiplier;
1153          glLightfv(GL_LIGHT0 + id, GL_AMBIENT, color);
1154          color[0] = light.specular.r * light.multiplier;
1155          color[1] = light.specular.g * light.multiplier;
1156          color[2] = light.specular.b * light.multiplier;
1157          glLightfv(GL_LIGHT0 + id, GL_SPECULAR,color);
1158
1159          if(lightObject)
1160          {
1161             Vector3D positionVector;
1162             if(light.flags.spot)
1163             {
1164                if(lightObject.flags.root || !lightObject.parent)
1165                {
1166                   positionVector = lightObject.transform.position;
1167                   positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
1168                }
1169                else
1170                {
1171                   positionVector.MultMatrix(lightObject.transform.position, lightObject.parent.matrix);
1172                   if(display.display3D.camera)
1173                      positionVector.Subtract(positionVector, display.display3D.camera.cPosition);
1174                }
1175                position[3] = 1;
1176             }
1177             else
1178             {
1179                if(!light.direction.x && !light.direction.y && !light.direction.z)
1180                {
1181                   Vector3Df vector { 0,0,-1 };
1182                   Matrix mat;
1183                   mat.RotationQuaternion(light.orientation);
1184                   positionVector.MultMatrixf(vector, mat);
1185                }
1186                else
1187                {
1188                   positionVector = light.direction;
1189                   position[3] = 1;
1190                }
1191             }
1192
1193             position[0] = (float)positionVector.x;
1194             position[1] = (float)positionVector.y;
1195             position[2] = (float)positionVector.z;
1196
1197             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
1198       CocoaGlAssert();
1199
1200             if(light.flags.attenuation)
1201             {
1202                glLightf(GL_LIGHT0 + id, GL_CONSTANT_ATTENUATION, light.Kc);
1203       CocoaGlAssert();
1204                glLightf(GL_LIGHT0 + id, GL_LINEAR_ATTENUATION, light.Kl);
1205       CocoaGlAssert();
1206                glLightf(GL_LIGHT0 + id, GL_QUADRATIC_ATTENUATION, light.Kq);
1207       CocoaGlAssert();
1208             }
1209
1210             if(light.flags.spot)
1211             {
1212                float exponent = 0;
1213                #define MAXLIGHT  0.9
1214                float direction[4] = { (float)light.direction.x, (float)light.direction.y, (float)light.direction.z, 1 };
1215                // Figure out exponent out of the hot spot
1216                exponent = (float)(log(MAXLIGHT) / log(cos((light.hotSpot / 2))));
1217
1218                glLightfv(GL_LIGHT0 + id, GL_SPOT_DIRECTION, direction);
1219       CocoaGlAssert();
1220                glLightf(GL_LIGHT0 + id, GL_SPOT_CUTOFF, (float)(light.fallOff / 2));
1221       CocoaGlAssert();
1222                glLightf(GL_LIGHT0 + id, GL_SPOT_EXPONENT, exponent);
1223       CocoaGlAssert();
1224             }
1225          }
1226          else
1227          {
1228             Vector3Df vector { 0,0,-1 };
1229             Vector3Df direction;
1230             Matrix mat;
1231
1232             mat.RotationQuaternion(light.orientation);
1233             direction.MultMatrix(vector, mat);
1234
1235             position[0] = direction.x;
1236             position[1] = direction.y;
1237             position[2] = direction.z;
1238
1239             glLightfv(GL_LIGHT0 + id, GL_POSITION, position);
1240       CocoaGlAssert();
1241          }
1242       }
1243       else
1244          glDisable(GL_LIGHT0 + id);
1245       CocoaGlAssert();
1246    }
1247
1248    void SetCamera(Display display, Surface surface, Camera camera)
1249    {
1250       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1251       if(camera)
1252       {
1253          int left = surface.box.left + surface.offset.x;
1254          int top = surface.box.top  + surface.offset.y;
1255          int right = surface.box.right + surface.offset.x;
1256          int bottom = surface.box.bottom + surface.offset.y;
1257          float origX = surface.offset.x + camera.origin.x;
1258          float origY = surface.offset.y + camera.origin.y;
1259          int x = left;
1260          int y = display.height - bottom - 1;
1261          int w = right - left + 1;
1262          int h = bottom - top + 1;
1263
1264          // *** ViewPort ***
1265          glViewport(x, y, w, h);
1266
1267          // *** Projection Matrix ***
1268          if(!display.display3D.camera)
1269             glPushMatrix();
1270          else
1271             glMatrixMode(GL_PROJECTION);
1272          if(display.display3D.collectingHits)
1273          {
1274             float pickX = display.display3D.pickX + surface.offset.x;
1275             float pickY = display.height - (display.display3D.pickY + surface.offset.y) - 1;
1276             Matrix pickMatrix
1277             {
1278                {
1279                   w / display.display3D.pickWidth, 0, 0, 0,
1280                   0, h / display.display3D.pickHeight, 0, 0,
1281                   0, 0, 1, 0,
1282                   (w + 2.0f * (x - pickX)) / display.display3D.pickWidth,
1283                   (h + 2.0f * (y - pickY)) / display.display3D.pickHeight, 0, 1
1284                }
1285             };
1286             glLoadMatrixd(pickMatrix.array);
1287          }
1288          else
1289             glLoadIdentity();
1290          glFrustum(
1291             (left   - origX) * camera.zMin / camera.focalX,
1292             (right  - origX) * camera.zMin / camera.focalX,
1293             (bottom - origY) * camera.zMin / camera.focalY,
1294             (top    - origY) * camera.zMin / camera.focalY,
1295             camera.zMin, camera.zMax);
1296
1297          glDisable(GL_BLEND);
1298
1299          // *** Z Inverted Identity Matrix ***
1300          glMatrixMode(GL_MODELVIEW);
1301          if(!display.display3D.camera)
1302             glPushMatrix();
1303
1304          glLoadIdentity();
1305          glScalef(1.0f, 1.0f, -1.0f);
1306
1307          // *** View Matrix ***
1308          glMultMatrixd(camera.viewMatrix.array);
1309
1310          // *** Lights ***
1311          // ...
1312
1313          glEnable(GL_DEPTH_TEST);
1314          glEnable(GL_LIGHTING);
1315          glShadeModel(GL_SMOOTH);
1316          glDepthMask((byte)bool::true);
1317
1318          glEnable(GL_MULTISAMPLE_ARB);
1319       }
1320       else if(display.display3D.camera)
1321       {
1322          glViewport(0,0,display.width,display.height);
1323
1324          glDisable(GL_CULL_FACE);
1325          glDisable(GL_DEPTH_TEST);
1326          glDisable(GL_LIGHTING);
1327          glDisable(GL_FOG);
1328          glDisable(GL_TEXTURE_2D);
1329          glShadeModel(GL_FLAT);
1330          glEnable(GL_BLEND);
1331          glDisable(GL_MULTISAMPLE_ARB);
1332
1333          // *** Restore 2D MODELVIEW Matrix ***
1334          glPopMatrix();
1335
1336          // *** Restore 2D PROJECTION Matrix ***
1337          glMatrixMode(GL_PROJECTION);
1338          glPopMatrix();
1339       }
1340
1341       if(glBindBufferARB)
1342          glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1343       printf("glGetError():%i\n", glGetError());
1344    }
1345
1346    void ApplyMaterial(Display display, Material material, Mesh mesh)
1347    {
1348       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1349       // Basic Properties
1350       if(material.flags.doubleSided)
1351       {
1352          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, !material.flags.singleSideLight);
1353          glDisable(GL_CULL_FACE);
1354       }
1355       else
1356       {
1357          glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, bool::false);
1358          glEnable(GL_CULL_FACE);
1359       }
1360
1361       // Fog
1362       if(material.flags.noFog)
1363          glDisable(GL_FOG);
1364       else
1365          glEnable(GL_FOG);
1366
1367       // Maps
1368       if(material.baseMap && mesh.texCoords)
1369       {
1370          Bitmap map = material.baseMap;
1371          glEnable(GL_TEXTURE_2D);
1372          glBindTexture(GL_TEXTURE_2D, (uint)map.driverData);
1373
1374          if(material.flags.tile)
1375          {
1376             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1377             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1378          }
1379          else
1380          {
1381             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1382             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1383          }
1384       }
1385       else
1386          glDisable(GL_TEXTURE_2D);
1387
1388       if(mesh.flags.colors)
1389       {
1390          glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
1391          glEnable(GL_COLOR_MATERIAL);
1392       }
1393       else
1394       {
1395          glDisable(GL_COLOR_MATERIAL);
1396          {
1397             float color[4] = { material.diffuse.r, material.diffuse.g, material.diffuse.b, material.opacity };
1398             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
1399          }
1400          {
1401             float color[4] = { material.ambient.r, material.ambient.g, material.ambient.b, 0 };
1402             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color);
1403          }
1404       }
1405       {
1406          float color[4] = { material.specular.r, material.specular.g, material.specular.b, 0 };
1407          glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color);
1408       }
1409       {
1410          float color[4] = { material.emissive.r, material.emissive.g, material.emissive.b, 0 };
1411          glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, color);
1412       }
1413
1414       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &material.power);
1415    }
1416
1417    void FreeMesh(DisplaySystem displaySystem, Mesh mesh)
1418    {
1419       MeshData meshData = mesh.data;
1420       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1421       if(meshData)
1422       {
1423          if(!mesh.flags.vertices)
1424          {
1425             if(meshData.vertices)
1426             {
1427                glDeleteBuffersARB(1, &meshData.vertices);
1428                meshData.vertices = 0;
1429             }
1430             delete mesh.vertices;
1431          }
1432          if(!mesh.flags.normals)
1433          {
1434             if(meshData.normals)
1435             {
1436                glDeleteBuffersARB(1, &meshData.normals);
1437                meshData.normals = 0;
1438             }
1439             delete mesh.normals;
1440          }
1441          if(!mesh.flags.texCoords1)
1442          {
1443             if(meshData.texCoords)
1444             {
1445                glDeleteBuffersARB(1, &meshData.texCoords);
1446                meshData.texCoords = 0;
1447             }
1448             delete mesh.texCoords;
1449          }
1450          if(!mesh.flags.texCoords2)
1451          {
1452             if(meshData.texCoords2)
1453             {
1454                glDeleteBuffersARB(1, &meshData.texCoords2);
1455                meshData.texCoords2 = 0;
1456             }
1457          }
1458          if(!mesh.flags.colors)
1459          {
1460             if(meshData.colors)
1461             {
1462                glDeleteBuffersARB(1, &meshData.colors);
1463                meshData.colors = 0;
1464             }
1465          }
1466          if(!mesh.flags)
1467          {
1468             delete meshData;
1469             mesh.data = null;
1470          }
1471       }
1472    }
1473
1474    bool AllocateMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags, int nVertices)
1475    {
1476       bool result = false;
1477       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1478       if(mesh.data)
1479       {
1480          OGLMesh oglMesh = mesh.data;
1481          if(mesh.nVertices == nVertices)
1482          {
1483             // Same number of vertices, adding features (Leaves the other features pointers alone)
1484             if(mesh.flags != flags)
1485             {
1486                if(!mesh.flags.vertices && flags.vertices)
1487                {
1488                   if(flags.doubleVertices)
1489                   {
1490                      mesh.vertices = (Vector3Df *)new Vector3D[nVertices];
1491                   }
1492                   else
1493                      mesh.vertices = new Vector3Df[nVertices];
1494                   if(!oglMesh.vertices)
1495                      GLGenBuffers(1, &oglMesh.vertices);
1496                }
1497                if(!mesh.flags.normals && flags.normals)
1498                {
1499                   if(flags.doubleNormals)
1500                   {
1501                      mesh.normals = (Vector3Df *)new Vector3D[nVertices];
1502                   }
1503                   else
1504                      mesh.normals = new Vector3Df[nVertices];
1505                   if(!oglMesh.normals)
1506                      GLGenBuffers( 1, &oglMesh.normals);
1507                }
1508                if(!mesh.flags.texCoords1 && flags.texCoords1)
1509                {
1510                   mesh.texCoords = new Pointf[nVertices];
1511                   if(!oglMesh.texCoords)
1512                      GLGenBuffers( 1, &oglMesh.texCoords);
1513                }
1514                if(!mesh.flags.colors && flags.colors)
1515                {
1516                   mesh.colors = new ColorRGBAf[nVertices];
1517                   if(!oglMesh.colors)
1518                      GLGenBuffers( 1, &oglMesh.colors);
1519                }
1520             }
1521          }
1522          else
1523          {
1524             // New number of vertices, reallocate all current and new features
1525             flags |= mesh.flags;
1526             if(flags.vertices)
1527             {
1528                if(flags.doubleVertices)
1529                {
1530                   mesh.vertices = (Vector3Df *)renew mesh.vertices Vector3D[nVertices];
1531                }
1532                else
1533                   mesh.vertices = renew mesh.vertices Vector3Df[nVertices];
1534                if(!oglMesh.vertices)
1535                   GLGenBuffers(1, &oglMesh.vertices);
1536             }
1537             if(flags.normals)
1538             {
1539                if(flags.doubleNormals)
1540                {
1541                   mesh.normals = (Vector3Df *)renew mesh.normals Vector3D[nVertices];
1542                }
1543                else
1544                   mesh.normals = renew mesh.normals Vector3Df[nVertices];
1545                if(!oglMesh.normals)
1546                   GLGenBuffers( 1, &oglMesh.normals);
1547             }
1548             if(flags.texCoords1)
1549             {
1550                mesh.texCoords = renew mesh.texCoords Pointf[nVertices];
1551                if(!oglMesh.texCoords)
1552                   GLGenBuffers( 1, &oglMesh.texCoords);
1553             }
1554             if(flags.colors)
1555             {
1556                mesh.colors = renew mesh.colors ColorRGBAf[nVertices];
1557                if(!oglMesh.colors)
1558                   GLGenBuffers( 1, &oglMesh.colors);
1559             }
1560          }
1561          result = true;
1562       }
1563       return result;
1564    }
1565
1566    void UnlockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1567    {
1568       MeshData meshData = mesh.data;
1569       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1570
1571       if(!flags) flags = mesh.flags;
1572
1573       if(glGenBuffersARB)
1574       {
1575          if(!(flags.vertices) || meshData.vertices)
1576          {
1577             glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.vertices);
1578             glBufferDataARB( GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleVertices ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.vertices, GL_STATIC_DRAW_ARB );
1579          }
1580
1581          if(!(flags.normals) || meshData.normals)
1582          {
1583             glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.normals);
1584             glBufferDataARB( GL_ARRAY_BUFFER_ARB, mesh.nVertices * (mesh.flags.doubleNormals ? sizeof(Vector3D) : sizeof(Vector3Df)), mesh.normals, GL_STATIC_DRAW_ARB );
1585          }
1586
1587          if(!(flags.texCoords1) || meshData.texCoords)
1588          {
1589             glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.texCoords);
1590             glBufferDataARB( GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(Pointf), mesh.texCoords, GL_STATIC_DRAW_ARB );
1591          }
1592
1593          if(!(flags.colors) || meshData.colors)
1594          {
1595             glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.colors);
1596             glBufferDataARB( GL_ARRAY_BUFFER_ARB, mesh.nVertices * sizeof(ColorRGBAf), mesh.colors, GL_STATIC_DRAW_ARB );
1597          }
1598
1599          glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
1600       }
1601    }
1602
1603    bool LockMesh(DisplaySystem displaySystem, Mesh mesh, MeshFeatures flags)
1604    {
1605       bool result = true;
1606       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1607       return result;
1608    }
1609
1610    void FreeIndices(DisplaySystem displaySystem, IndexData indexData)
1611    {
1612       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1613
1614       if(indexData)
1615       {
1616          if(indexData.buffer)
1617             glDeleteBuffersARB(1, &indexData.buffer);
1618          delete indexData.indices;
1619          delete indexData;
1620       }
1621    }
1622
1623    void * AllocateIndices(DisplaySystem displaySystem, int nIndices, bool indices32bit)
1624    {
1625       IndexData indexData = IndexData { };
1626       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1627       if(indexData)
1628       {
1629          indexData.indices = (void *)(indices32bit ? new uint32[nIndices] : new uint16[nIndices]);
1630          if(glGenBuffersARB)
1631             glGenBuffersARB( 1, &indexData.buffer);
1632          indexData.nIndices = nIndices;
1633       }
1634       return indexData;
1635    }
1636
1637    void UnlockIndices(DisplaySystem displaySystem, IndexData indexData, bool indices32bit, int nIndices)
1638    {
1639       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1640       if(glGenBuffersARB)
1641       {
1642          glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, indexData.buffer);
1643          glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, nIndices * (indices32bit ? sizeof(uint32) : sizeof(uint16)),
1644             indexData.indices, GL_STATIC_DRAW_ARB);
1645          glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1646       }
1647    }
1648
1649    uint16 * LockIndices(DisplaySystem displaySystem, IndexData indexData)
1650    {
1651       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1652
1653       return indexData.indices;
1654    }
1655
1656    void SelectMesh(Display display, Mesh mesh)
1657    {
1658       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1659
1660       /*if(display.display3D.mesh && glUnlockArraysEXT)
1661          glUnlockArraysEXT();*/
1662
1663       if(mesh)
1664       {
1665          //DisplayData displayData = display.driverData;
1666          MeshData meshData = mesh.data;
1667
1668          // *** Vertex Stream ***
1669          glEnableClientState(GL_VERTEX_ARRAY);
1670          if(!display.display3D.collectingHits && meshData)
1671          {
1672             if(glBindBufferARB)
1673                glBindBufferARB(GL_ARRAY_BUFFER_ARB, meshData.vertices);
1674             glVertexPointer(3, mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT, 0, glBindBufferARB ? null : mesh.vertices);
1675
1676             // *** Normals Stream ***
1677             if(mesh.normals)
1678             {
1679                glEnableClientState(GL_NORMAL_ARRAY);
1680                if(glBindBufferARB)
1681                   glBindBufferARB(GL_ARRAY_BUFFER_ARB, meshData.normals);
1682                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, glBindBufferARB ? null : mesh.normals);
1683             }
1684             else
1685             {
1686                glDisableClientState(GL_NORMAL_ARRAY);
1687             }
1688
1689             // *** Texture Coordinates Stream ***
1690             if(mesh.texCoords)
1691             {
1692                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1693                if(glBindBufferARB)
1694                   glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.texCoords);
1695                glTexCoordPointer(2, GL_FLOAT, 0, glBindBufferARB ? null : mesh.texCoords);
1696             }
1697             else
1698             {
1699                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1700             }
1701
1702             // *** Color Stream ***
1703             if(mesh.colors)
1704             {
1705                glEnableClientState(GL_COLOR_ARRAY);
1706                if(glBindBufferARB)
1707                   glBindBufferARB( GL_ARRAY_BUFFER_ARB, meshData.colors);
1708                glColorPointer(4, GL_FLOAT, 0, glBindBufferARB ? null : mesh.colors);
1709             }
1710             else
1711             {
1712                glDisableClientState(GL_COLOR_ARRAY);
1713             }
1714          }
1715          else
1716          {
1717             if(glBindBufferARB)
1718                glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0);
1719             glVertexPointer(3,mesh.flags.doubleVertices ? GL_DOUBLE : GL_FLOAT,0,mesh.vertices);
1720             if(mesh.normals && !display.display3D.collectingHits)
1721             {
1722                glEnableClientState(GL_NORMAL_ARRAY);
1723                glNormalPointer(mesh.flags.doubleNormals ? GL_DOUBLE : GL_FLOAT, 0, mesh.normals);
1724             }
1725             else
1726                glDisableClientState(GL_NORMAL_ARRAY);
1727             if(mesh.texCoords && !display.display3D.collectingHits)
1728             {
1729                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1730                glTexCoordPointer(2, GL_FLOAT, 0, mesh.texCoords);
1731             }
1732             else
1733                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1734             if(mesh.colors && !display.display3D.collectingHits)
1735             {
1736                glEnableClientState(GL_COLOR_ARRAY);
1737                glColorPointer(4, GL_FLOAT, 0, mesh.colors);
1738             }
1739             else
1740                glDisableClientState(GL_COLOR_ARRAY);
1741          }
1742
1743          //if(glLockArraysEXT) glLockArraysEXT(0, mesh.nVertices);
1744       }
1745       else if(glBindBufferARB)
1746          glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1747    }
1748
1749    void DrawPrimitives(Display display, PrimitiveSingle * primitive, Mesh mesh)
1750    {
1751       //DisplayData displayData = display.driverData;
1752       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1753
1754       if(primitive->type.vertexRange)
1755          glDrawArrays(primitiveTypes[primitive->type.primitiveType], primitive->first, primitive->nVertices);
1756       else
1757       {
1758          //    *** Hoping the data won't be uploaded at all (Won't really work if another group of the mesh is using the mesh ) ***
1759          // HACK TO SPEED THINGS UP...
1760          if(primitive->nIndices < (mesh.nVertices >> 2) && !primitive->type.indices32bit)
1761          {
1762             int c;
1763             glBegin(primitiveTypes[primitive->type.primitiveType]);
1764             if(primitive->data)
1765             {
1766                IndexData indexData = primitive->data;
1767                MeshFeatures flags = mesh.flags;
1768                for(c = 0; c < primitive->nIndices; c++)
1769                {
1770                   short index = ((short *) indexData.indices)[c];
1771                   if(flags.normals) glNormal3fv((float *)&mesh.normals[index]);
1772                   if(flags.texCoords1) glTexCoord2fv((float *)&mesh.texCoords[index]);
1773                   if(flags.colors) glColor4fv((float *)&mesh.colors[index]);
1774                   glVertex3fv((float *)&mesh.vertices[index]);
1775                }
1776             }
1777             glEnd();
1778          }
1779          else
1780          {
1781             IndexData indexData = primitive->data;
1782
1783             if(!display.display3D.collectingHits && glBindBufferARB && indexData)
1784             {
1785                glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexData.buffer);
1786                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
1787                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
1788                glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1789             }
1790             else if(indexData)
1791                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
1792                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, indexData.indices);
1793             else
1794                glDrawElements(primitiveTypes[primitive->type.primitiveType], primitive->nIndices,
1795                   primitive->type.indices32bit ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, primitive->indices);
1796          }
1797       }
1798    }
1799
1800    void PushMatrix(Display display)
1801    {
1802       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1803       glPushMatrix();
1804    }
1805
1806    void PopMatrix(Display display, bool setMatrix)
1807    {
1808       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1809       glPopMatrix();
1810    }
1811
1812    void SetTransform(Display display, Matrix transMatrix, bool viewSpace, bool useCamera)
1813    {
1814       Matrix matrix = transMatrix;
1815       Camera camera = useCamera ? display.display3D.camera : null;
1816
1817       printf("CocoaOpenGLDisplayDriver: STUB! %s:%i\n", __FILE__, __LINE__);
1818       if(viewSpace)
1819       {
1820          glLoadIdentity();
1821          glScalef(1.0f, 1.0f, -1.0f);
1822       }
1823       else if(camera)
1824       {
1825          glTranslated(
1826             matrix.m[3][0] - camera.cPosition.x,
1827             matrix.m[3][1] - camera.cPosition.y,
1828             matrix.m[3][2] - camera.cPosition.z);
1829       }
1830       else
1831          glTranslated(
1832             matrix.m[3][0],
1833             matrix.m[3][1],
1834             matrix.m[3][2]);
1835
1836       matrix.m[3][0] = 0;
1837       matrix.m[3][1] = 0;
1838       matrix.m[3][2] = 0;
1839
1840       glMultMatrixd(matrix.array);
1841    }
1842 #endif
1843 }