3 /* -------------------------------------------------------------------------- */
8 /* -------------------------------------------------------------------------- */
10 #define WINDOW_WIDTH 640
11 #define WINDOW_HEIGHT 480
14 #define NORMAL_ARRAY 1
15 #define TEXCOORD_ARRAY 2
19 /* -------------------------------------------------------------------------- */
21 EGLNativeDisplayType eglX11Display;
22 EGLNativeWindowType eglX11Window;
23 EGLDisplay eglDisplay = 0;
24 EGLConfig eglConfig = 0;
25 EGLSurface eglSurface = 0;
26 EGLContext eglContext = 0;
28 /* -------------------------------------------------------------------------- */
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;
37 /* -------------------------------------------------------------------------- */
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);
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);
53 /* -------------------------------------------------------------------------- */
55 EXPORT int mid_module_loaded(void)
57 ni_register_driver("mid", handles_resource, sync_resource);
61 k_gl_register_reshape(reshape);
62 k_gl_register_draw(draw);
63 k_gl_register_key(key);
65 k_log_out("MID Driver initialised");
70 EXPORT int mid_module_event(void* data)
72 k_log_out("MID got event: %p", data);
78 EXPORT int mid_module_tick(void)
80 if(!drawStuff(WINDOW_WIDTH, WINDOW_HEIGHT)) destroyEGL();
84 /* -------------------------------------------------------------------------- */
86 int handles_resource(char* name)
91 void sync_resource(ni_resource* res)
95 /* -------------------------------------------------------------------------- */
99 if(!getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT)) destroyEGL();
100 if(!setUpEGL()) destroyEGL();
101 if(!useTheProgram()) destroyEGL();
102 if(!setUpTnL()) destroyEGL();
105 void reshape(int width, int height)
111 if(!drawStuff(WINDOW_WIDTH, WINDOW_HEIGHT)) destroyEGL();
115 void key(unsigned char k, int down)
118 if(event.xkey.keycode == 113) viewAngle += 0.1;
119 if(event.xkey.keycode == 114) viewAngle -= 0.1;
121 if(k==SHIFT && down){ shift=1; return; }
122 if(k==SHIFT && !down){ shift=0; return; }
125 if(shift) k-=('a'-'A');
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;
134 if(zco< -35) zco= -35;
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;
142 if(zco< -35) zco= -35;
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;
150 if(zco< -35) zco= -35;
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;
158 if(zco< -35) zco= -35;
163 if(yco< 0.2) yco= 0.2;
169 view_roty += speed*20;
172 view_roty -= speed*20;
192 /* -------------------------------------------------------------------------- */
194 /* need a callback to call this */
197 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
198 eglTerminate(eglDisplay);
201 /* ------------------------------------------------------------- */
203 int isEGLError(char* where)
205 EGLint err = eglGetError();
206 if(err != EGL_SUCCESS) {
207 printf("EGL failed at %s (%d).\n", where, err);
215 eglDisplay = eglGetDisplay(eglX11Display);
217 EGLint iMajorVersion, iMinorVersion;
218 if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
219 printf("Error: eglInitialize() failed.\n");
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;
230 EGLint pi32ContextAttribs[3];
231 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
232 pi32ContextAttribs[1] = 2;
233 pi32ContextAttribs[2] = EGL_NONE;
236 if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
237 printf("Error: eglChooseConfig() failed.\n");
241 eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglX11Window, NULL);
242 if(isEGLError("eglCreateWindowSurface")) return 0;
244 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
245 if(isEGLError("eglCreateContext")) return 0;
247 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
248 if(isEGLError("eglMakeCurrent")) return 0;
253 /* ------------------------------------------------------------- */
255 GLuint isShaderError(GLuint thing)
257 GLint isShader = glIsShader(thing);
261 glGetShaderiv(thing, GL_COMPILE_STATUS, &ok);
263 glGetProgramiv(thing, GL_LINK_STATUS, &ok);
269 glGetShaderiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
271 glGetProgramiv(thing, GL_INFO_LOG_LENGTH, &infoLen);
274 char* infoLog = malloc(sizeof(char)*infoLen);
276 glGetShaderInfoLog(thing, infoLen, NULL, infoLog);
278 glGetProgramInfoLog(thing, infoLen, NULL, infoLog);
280 printf("%s: %s\n", isShader? "Shader compile": "Program link", infoLog);
286 char* file2string(const char *path)
292 if(!(fd=fopen(path, "r"))) {
293 fprintf(stderr, "Can't open file '%s' for reading\n", path);
297 fseek(fd, 0, SEEK_END);
299 fseek(fd, 0, SEEK_SET);
301 if(!(str=malloc(len*sizeof(char)))) {
302 fprintf(stderr, "Can't malloc space for '%s'\n", path);
306 r = fread(str, sizeof(char), len, fd);
315 /* ------------------------------------------------------------- */
320 unsigned int numberOfVertices;
321 unsigned int posStep;
322 unsigned int normStep;
326 float viewAngle = 0.0;
330 const char *vsSource = file2string("tnl.vert");
331 const char *fsSource = file2string("tnl.frag");
333 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
334 glShaderSource(vs, 1, &vsSource, NULL);
336 if(isShaderError(vs)) return 0;
338 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
339 glShaderSource(fs, 1, &fsSource, NULL);
341 if(isShaderError(fs)) return 0;
343 free((void*)vsSource);
344 free((void*)fsSource);
346 program = glCreateProgram();
347 glAttachShader(program, vs);
348 glAttachShader(program, fs);
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");
355 glLinkProgram(program);
356 if(isShaderError(program)) return 0;
358 glUseProgram(program);
360 glUniform3f(glGetUniformLocation(program, "frameLightDirection"), 1.0, 0.0, 1.0);
361 glUniform1i(glGetUniformLocation(program, "texture"), 0); /* 0 ?? */
368 glClearColor(1.0f, 1.0f, 0.0f, 0.0f);
370 glGenTextures(1, &texture);
371 glBindTexture(GL_TEXTURE_2D, texture);
373 GLuint* td = malloc(sizeof(GLuint)*TEX_SIZE*TEX_SIZE);
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;
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 );
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
391 0.4f,-0.0f,0.0f, // Pos
392 0.0f,0.0f,1.0f, // Normal
393 1.0f,0.0f, // TexCoord
395 0.0f,0.4f,0.4f, // Pos
396 0.5f,0.5f,0.5f, // Normal
397 0.5f,1.0f, // TexCoord
399 0.4f,0.0f,0.4f, // Pos
400 0.5f,0.5f,0.5f, // Normal
401 0.5f,0.0f, // TexCoord
403 0.4f,0.4f,0.4f, // Pos
404 0.0f,0.0f,1.0f, // Normal
405 0.0f,0.0f, // TexCoord
409 numberOfVertices = 4;
410 posStep = 3 * sizeof(GLfloat);
411 normStep = 3 * sizeof(GLfloat);
412 tcStep = 2 * sizeof(GLfloat);
413 stride = posStep + normStep + tcStep;
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);
423 int drawStuff(int width, int height)
425 glViewport(0, 0, width, height);
426 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
428 float TransRotScaleVerticeMatrix[] = {
429 cos(angle), 0, sin(angle), 0,
431 -sin(angle), 0, cos(angle), 0,
435 float ModelViewProjectionMatrix[] = {
436 cos(viewAngle), 0, sin(viewAngle), 0,
438 -sin(viewAngle), 0, cos(viewAngle), 0,
442 float TransRotScaleNormalMatrix[] = {
443 cos(angle), 0, sin(angle),
445 -sin(angle), 0, cos(angle)
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);
453 glBindBuffer(GL_ARRAY_BUFFER, vbo);
455 glEnableVertexAttribArray(POS_ARRAY);
456 glVertexAttribPointer(POS_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, 0);
458 glEnableVertexAttribArray(NORMAL_ARRAY);
459 glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, stride, (void*)posStep );
461 glEnableVertexAttribArray(TEXCOORD_ARRAY);
462 glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, stride, (void*)(posStep + normStep) );
464 glDrawArrays(GL_TRIANGLE_STRIP, 0, numberOfVertices);
466 glBindBuffer(GL_ARRAY_BUFFER, 0);
468 eglSwapBuffers(eglDisplay, eglSurface);
472 return !isEGLError("drawStuff");
476 glDeleteTextures(1, &texture);
477 glDeleteBuffers(1, &vbo);
478 glDeleteProgram(program);
483 /* ------------------------------------------------------------- */
485 #include <X11/Xutil.h>
487 Window x11Window = 0;
488 Display* x11Display = 0;
490 XVisualInfo* x11Visual = 0;
491 Colormap x11Colormap = 0;
493 int getX11Display(int windowwidth, int windowheight)
495 x11Display = XOpenDisplay(0);
498 printf("Error: Unable to open X display\n");
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);
509 printf("Error: Unable to acquire visual\n");
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;
520 x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
521 0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
522 XMapWindow(x11Display, x11Window);
525 eglX11Display = (EGLNativeDisplayType)x11Display;
526 eglX11Window = (EGLNativeWindowType) x11Window;
533 if(x11Window) XDestroyWindow(x11Display, x11Window);
534 if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
535 if(x11Display) XCloseDisplay( x11Display);
540 int nm = XPending(x11Display);
542 for(m=0; m< nm; m++) {
544 XNextEvent(x11Display, &event);
556 /* ------------------------------------------------------------- */