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