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