first import of old cilux linux platform code
[cilux] / src / drivers / mid / mid.c
1
2
3 /* -------------------------------------------------------------------------- */
4
5 #include <kernelapi.h>
6 #include <ni.h>
7
8 #include <math.h>
9
10 /* ------------------------------------------------------------- */
11
12 #include <math.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include "X11/Xutil.h"
17
18 #include <EGL/egl.h>
19 #include <GLES2/gl2.h>
20
21 #define WINDOW_WIDTH  640
22 #define WINDOW_HEIGHT 480
23
24 #define POS_ARRAY      0
25 #define NORMAL_ARRAY   1
26 #define TEXCOORD_ARRAY 2
27
28 #define TEX_SIZE 128
29
30 /* ------------------------------------------------------------- */
31
32 Window        x11Window   = 0;
33 Display*      x11Display  = 0;
34 long          x11Screen   = 0;
35 XVisualInfo*  x11Visual   = 0;
36 Colormap      x11Colormap = 0;
37
38 EGLDisplay    eglDisplay = 0;
39 EGLConfig     eglConfig  = 0;
40 EGLSurface    eglSurface = 0;
41 EGLContext    eglContext = 0;
42
43 /* ------------------------------------------------------------- */
44
45 /* -------------------------------------------------------------------------- */
46
47 #define GLfloat float
48 static GLfloat   xco=   0;
49 static GLfloat   yco=   1;
50 static GLfloat   zco= -35;
51 static GLfloat   view_rotx=0.0, view_roty=0.0, view_rotz=0.0;
52 static int       shift=0;
53
54 /* -------------------------------------------------------------------------- */
55
56 static int  handles_resource(char* name);
57 static void sync_resource(ni_resource* res);
58 static void init_gl(void);
59 static void make_world(void);
60 static void reshape(int width, int height);
61 static void draw(void);
62 static void key(unsigned char k, int down);
63 static void plane(void* n);
64 static void double_cube(void* s);
65 static void cube(GLfloat size, int outside);
66 static int  set_object(char* n,
67                        GLfloat x, GLfloat y, GLfloat z, GLfloat angle,
68                        void (*listFn)(void*),
69                        void*  listFnArgs        );
70
71 /* -------------------------------------------------------------------------- */
72
73 EXPORT int mid_module_loaded(void)
74 {
75         ni_register_driver("mid", handles_resource, sync_resource);
76
77         init_gl();
78         make_world();
79
80         k_gl_register_reshape(reshape);
81         k_gl_register_draw(draw);
82         k_gl_register_key(key);
83
84         k_log_out("MID Driver initialised");
85
86         testloop();
87
88         return 1;
89 }
90
91 EXPORT int mid_module_event(void* data)
92 {
93         k_log_out("MID got event: %p", data);
94         ni_event* evt=data;
95         ni_event_delete(evt);
96         return 1;
97 }
98
99 /* -------------------------------------------------------------------------- */
100
101 int handles_resource(char* name)
102 {
103         return 0;
104 }
105
106 void sync_resource(ni_resource* res)
107 {
108 }
109
110 /* -------------------------------------------------------------------------- */
111
112 void init_gl(void)
113 {
114 }
115
116 void make_world(void)
117 {
118 }
119
120 void reshape(int width, int height)
121 {
122 }
123
124 void draw(void)
125 {
126 }
127
128 #define SHIFT 0
129 void key(unsigned char k, int down)
130 {
131         if(k==SHIFT &&  down){ shift=1; return; }
132         if(k==SHIFT && !down){ shift=0; return; }
133         if(!down) return;
134
135         if(shift) k-=('a'-'A');
136
137         float speed=0.25;
138         switch (k) {
139         case 'H':
140                 xco-=speed*(float)sin((view_roty-90)*3.14/180);
141                 zco+=speed*(float)cos((view_roty-90)*3.14/180);
142                 if(xco< -35) xco= -35;
143                 if(xco>  35) xco=  35;
144                 if(zco< -35) zco= -35;
145                 if(zco>  35) zco=  35;
146         break;
147         case 'L':
148                 xco+=speed*(float)sin((view_roty-90)*3.14/180);
149                 zco-=speed*(float)cos((view_roty-90)*3.14/180);
150                 if(xco< -35) xco= -35;
151                 if(xco>  35) xco=  35;
152                 if(zco< -35) zco= -35;
153                 if(zco>  35) zco=  35;
154         break;
155         case 'i':
156                 xco-=speed*(float)sin(view_roty*3.14/180);
157                 zco+=speed*(float)cos(view_roty*3.14/180);
158                 if(xco< -35) xco= -35;
159                 if(xco>  35) xco=  35;
160                 if(zco< -35) zco= -35;
161                 if(zco>  35) zco=  35;
162         break;
163         case 'o':
164                 xco+=speed*(float)sin(view_roty*3.14/180);
165                 zco-=speed*(float)cos(view_roty*3.14/180);
166                 if(xco< -35) xco= -35;
167                 if(xco>  35) xco=  35;
168                 if(zco< -35) zco= -35;
169                 if(zco>  35) zco=  35;
170         break;
171         case 'j':
172                 yco-=speed;
173                 if(yco< 0.2) yco= 0.2;
174         break;
175         case 'k':
176                 yco+=speed;
177         break;
178         case 'l':
179                 view_roty += speed*20;
180         break;
181         case 'h':
182                 view_roty -= speed*20;
183         break;
184 /*
185         case 'J':
186                 view_rotx += 2.0;
187         break;
188         case 'K':
189                 view_rotx -= 2.0;
190         break;
191         case 'z':
192                 view_rotz += 2.0;
193         break;
194         case 'Z':
195                 view_rotz -= 2.0;
196         break;
197 */
198         default:
199         return;
200         }
201         draw();
202 }
203
204 /* -------------------------------------------------------------------------- */
205 /* ------------------------------------------------------------- */
206
207 void cleanupAndExit(int code)
208 {
209     eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
210     eglTerminate(eglDisplay);
211
212     if(x11Window)   XDestroyWindow(x11Display, x11Window);
213     if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
214     if(x11Display)  XCloseDisplay( x11Display);
215
216     exit(code);
217 }
218
219 /* ------------------------------------------------------------- */
220
221 void getX11Display(int windowwidth, int windowheight)
222 {
223     x11Display = XOpenDisplay(0);
224
225     if(!x11Display) {
226         printf("Error: Unable to open X display\n");
227         cleanupAndExit(-1);
228     }
229
230     x11Screen = XDefaultScreen(x11Display);
231     Window rootWindow = RootWindow(x11Display, x11Screen);
232     int depth = DefaultDepth(x11Display, x11Screen);
233     x11Visual = malloc(sizeof(XVisualInfo));
234     XMatchVisualInfo(x11Display, x11Screen, depth, TrueColor, x11Visual);
235
236     if(!x11Visual) {
237         printf("Error: Unable to acquire visual\n");
238         cleanupAndExit(-1);
239     }
240
241     x11Colormap = XCreateColormap(x11Display, rootWindow, x11Visual->visual, AllocNone);
242     XSetWindowAttributes XSWA;
243     XSWA.colormap = x11Colormap;
244     XSWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
245     unsigned int cwmask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
246
247     x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
248                               0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
249     XMapWindow(x11Display, x11Window);
250     XFlush(x11Display);
251 }
252
253 int isEGLError(char* where)
254 {
255     EGLint err = eglGetError();
256     if(err != EGL_SUCCESS) {
257         printf("EGL failed at %s (%d).\n", where, err);
258         return 1;
259     }
260     return 0;
261 }
262
263 void setUpEGL(void)
264 {
265     eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display);
266
267     EGLint iMajorVersion, iMinorVersion;
268     if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
269         printf("Error: eglInitialize() failed.\n");
270         cleanupAndExit( -1);
271     }
272
273     EGLint pi32ConfigAttribs[5];
274     pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
275     pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
276     pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
277     pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;    
278     pi32ConfigAttribs[4] = EGL_NONE;
279
280     EGLint pi32ContextAttribs[3];
281     pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
282     pi32ContextAttribs[1] = 2;
283     pi32ContextAttribs[2] = EGL_NONE;
284
285     int iConfigs;
286     if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
287         printf("Error: eglChooseConfig() failed.\n");
288         cleanupAndExit( -1);
289     }
290
291     eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)x11Window, NULL);
292     
293     if(isEGLError("eglCreateWindowSurface")) cleanupAndExit( -1);
294
295     eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
296
297     if(isEGLError("eglCreateContext")) cleanupAndExit( -1);
298
299     eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
300
301     if(isEGLError("eglMakeCurrent")) cleanupAndExit( -1);
302 }
303
304 /* ------------------------------------------------------------- */
305
306 GLuint isShaderError(GLuint thing)
307 {
308     GLint isShader = glIsShader(thing);
309
310     GLint ok;
311     if(isShader){
312         glGetShaderiv(thing, GL_COMPILE_STATUS, &ok);
313     }else{
314         glGetProgramiv(thing, GL_LINK_STATUS, &ok);
315     }
316     if(ok) return 0;
317
318     GLint infoLen=0;
319     if(isShader){
320         glGetShaderiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
321     }else{
322         glGetProgramiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
323     }
324     if(infoLen){
325          char* infoLog = malloc(sizeof(char)*infoLen);
326          if(isShader){
327               glGetShaderInfoLog(thing, infoLen, NULL, infoLog);
328          }else{
329               glGetProgramInfoLog(thing, infoLen, NULL, infoLog);
330          }
331          printf("%s: %s\n", isShader? "Shader compile": "Program link", infoLog);
332          free(infoLog);
333     }
334     return 1;
335 }
336
337 char* file2string(const char *path)
338 {
339     FILE *fd;
340     long len, r;
341     char *str;
342  
343     if(!(fd=fopen(path, "r"))) {
344         fprintf(stderr, "Can't open file '%s' for reading\n", path);
345         return NULL;
346     }
347  
348     fseek(fd, 0, SEEK_END);
349     len = ftell(fd);
350     fseek(fd, 0, SEEK_SET);
351  
352     if(!(str=malloc(len*sizeof(char)))) {
353         fprintf(stderr, "Can't malloc space for '%s'\n", path);
354         return NULL;
355     }
356  
357     r = fread(str, sizeof(char), len, fd);
358  
359     str[r-1] = '\0';
360  
361     fclose(fd);
362  
363     return str;
364 }
365
366 /* ------------------------------------------------------------- */
367
368 GLuint       program;
369 GLuint       texture;
370 GLuint       vbo;
371 unsigned int numberOfVertices;
372 unsigned int posStep;
373 unsigned int normStep;
374 unsigned int tcStep;
375 unsigned int stride;
376 float        angle=0.0;
377 float        viewAngle = 0.0;
378
379 GLuint useTheProgram()
380 {
381     const char *vsSource = file2string("tnl.vert");
382     const char *fsSource = file2string("tnl.frag");
383
384     GLuint vs = glCreateShader(GL_VERTEX_SHADER);
385     glShaderSource(vs, 1, &vsSource, NULL);
386     glCompileShader(vs);
387     if(isShaderError(vs)) return 0;
388  
389     GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
390     glShaderSource(fs, 1, &fsSource, NULL);
391     glCompileShader(fs);
392     if(isShaderError(fs)) return 0;
393  
394     free((void*)vsSource);
395     free((void*)fsSource);
396  
397     program = glCreateProgram();
398     glAttachShader(program, vs);
399     glAttachShader(program, fs);
400
401     glBindAttribLocation(program, POS_ARRAY,      "vertPos");
402     glBindAttribLocation(program, NORMAL_ARRAY,   "vertNormal");  /* vertNormal and vertTexCoord don't need to be bound here.. ? */
403     glBindAttribLocation(program, TEXCOORD_ARRAY, "vertTexCoord");
404
405     glLinkProgram(program);
406     if(isShaderError(program)) return 0;
407
408     glUseProgram(program);
409
410     glUniform3f(glGetUniformLocation(program, "frameLightDirection"), 1.0, 0.0, 1.0);
411     glUniform1i(glGetUniformLocation(program, "texture"), 0); /* 0 ?? */
412
413     return 1;
414 }
415
416 void setUpTnL(){
417
418     glGenTextures(1, &texture);
419     glBindTexture(GL_TEXTURE_2D, texture);
420
421     GLuint* td = malloc(sizeof(GLuint)*TEX_SIZE*TEX_SIZE);
422     int i,j;
423     for(i=0; i<TEX_SIZE; i++)
424     for(j=0; j<TEX_SIZE; j++) {
425         GLuint col = (255L<<24) + ((255L-j*2)<<16) + ((255L-i)<<8) + (255L-i*2);
426         if ( ((i*j)/8) % 2 ) col = (GLuint) (255L<<24) + (255L<<16) + (0L<<8) + (255L);
427         td[j*TEX_SIZE+i] = col;
428     }
429     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, td);
430     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
431     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
432     free(td);
433
434     GLfloat trivertices[] = {
435                              -0.4f,-0.4f,0.4f,  // Pos
436                               0.0f,0.0f,1.0f,   // Normal
437                               0.0f,0.0f,        // TexCoord
438
439                               0.4f,-0.0f,0.0f,  // Pos
440                               0.0f,0.0f,1.0f,   // Normal
441                               1.0f,0.0f,        // TexCoord
442
443                               0.0f,0.4f,0.4f,   // Pos
444                               0.5f,0.5f,0.5f,   // Normal
445                               0.5f,1.0f,        // TexCoord
446
447                               0.4f,0.0f,0.4f,   // Pos
448                               0.5f,0.5f,0.5f,   // Normal
449                               0.5f,0.0f,        // TexCoord
450
451                               0.4f,0.4f,0.4f,   // Pos
452                               0.0f,0.0f,1.0f,   // Normal
453                               0.0f,0.0f,        // TexCoord
454
455     };
456
457     numberOfVertices = 4;
458     posStep  = 3 * sizeof(GLfloat);
459     normStep = 3 * sizeof(GLfloat);
460     tcStep   = 2 * sizeof(GLfloat);
461     stride = posStep + normStep + tcStep;
462
463     glGenBuffers(1, &vbo);
464     glBindBuffer(GL_ARRAY_BUFFER, vbo);
465     glBufferData(GL_ARRAY_BUFFER, numberOfVertices * stride, trivertices, GL_STATIC_DRAW);
466     glBindBuffer(GL_ARRAY_BUFFER, 0);
467 }
468
469 int drawStuff(int width, int height)
470 {
471     glViewport(0, 0, width, height);
472     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
473
474     float TransRotScaleVerticeMatrix[] = {
475         cos(angle),  0, sin(angle), 0,
476         0,           1, 0,          0,
477         -sin(angle), 0, cos(angle), 0,
478         0,           0, 0,          1
479     };
480
481     float ModelViewProjectionMatrix[] = {
482         cos(viewAngle),  0, sin(viewAngle), 0,
483         0,               1, 0,              0,
484         -sin(viewAngle), 0, cos(viewAngle), 0,
485         0,               0, 0,              1
486     };
487
488     float TransRotScaleNormalMatrix[] = {
489         cos(angle),   0,   sin(angle),
490         0,            1,   0,
491         -sin(angle),  0,   cos(angle)
492     };
493
494     glUniformMatrix4fv(glGetUniformLocation(program, "frameTRSV"), 1, GL_FALSE, TransRotScaleVerticeMatrix);
495     glUniformMatrix4fv(glGetUniformLocation(program, "frameMVP"),  1, GL_FALSE, ModelViewProjectionMatrix);
496     glUniformMatrix3fv(glGetUniformLocation(program, "frameTRSN"), 1, GL_FALSE, TransRotScaleNormalMatrix);
497
498
499     glBindBuffer(GL_ARRAY_BUFFER, vbo);
500
501     glEnableVertexAttribArray(POS_ARRAY);
502     glVertexAttribPointer(POS_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, 0);
503
504     glEnableVertexAttribArray(NORMAL_ARRAY);
505     glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, (void*)posStep  );
506
507     glEnableVertexAttribArray(TEXCOORD_ARRAY);
508     glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, stride, (void*)(posStep + normStep) );
509
510     glDrawArrays(GL_TRIANGLE_STRIP, 0, numberOfVertices);
511
512     glBindBuffer(GL_ARRAY_BUFFER, 0);
513
514     eglSwapBuffers(eglDisplay, eglSurface);
515
516     angle += .001f;
517
518     return !isEGLError("drawStuff");
519 }
520
521 void deleteStuff(){
522     glDeleteTextures(1, &texture);
523     glDeleteBuffers(1, &vbo);
524     glDeleteProgram(program);
525 /*  glDeleteShader();
526     glDeleteShader();*/
527 }
528  
529 /* ------------------------------------------------------------- */
530
531 void testloop()
532 {
533     printf("Test OpenGL ES 2.0\n---------------------------\n");
534
535     getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT);
536
537     setUpEGL();
538  
539     glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
540
541     if(!useTheProgram()) cleanupAndExit(-1);
542     setUpTnL();
543
544     int done = 0;
545     while(!done){
546
547         if(!drawStuff(WINDOW_WIDTH, WINDOW_HEIGHT)) cleanupAndExit(-1);
548
549         int nm = XPending(x11Display);
550         int m;
551         for(m=0; m< nm; m++) {
552
553             XEvent event;
554             XNextEvent(x11Display, &event);
555             switch(event.type){
556                 case ButtonPress:
557                     done = 1;
558                 break;
559                 case KeyPress:
560                     if(event.xkey.keycode == 113) viewAngle += 0.1;
561                     if(event.xkey.keycode == 114) viewAngle -= 0.1;
562                 break;
563                 default:
564                 break;
565             }
566         }
567     }
568     cleanupAndExit(0);
569 }
570
571 /* ------------------------------------------------------------- */
572
573
574